c语言之动态内存管理及常见错误分析,柔性数组,内存划分

目录

 前言

一:malloc,calloc,realloc,free四大函数

1.malloc

2.free 

3.calloc

4.realloc 

二:常见错误分析 

1.malloc返回值不检查直接使用

2.对动态开辟空间的越界访问 

3.对非动态开辟空间free 

4.使用free释放动态开辟内存的一部分 

5.对同一块动态内存多次释放 

6.对动态内存空间未释放--内存泄漏 

三:柔性数组 

1.定义

2.特点 

3.使用 

4.内存分配规则 

5.非柔性数组方法 

6.柔性数组的优势 

四:c/c++中程序内存区域划分

接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧

 前言

对于c语言的动态内存管理是在原先定义数组时,数组的大小被指定,无法修改,可能造成空间的浪费或者空间不够造成越界访问,所以在此基础上提出用malloc,calloc,realloc,free四大函数来维护,自己开辟想要的空间大小,并自己释放,而柔性数组也是用来动态开辟空间的,接下来一一介绍

一:malloc,calloc,realloc,free四大函数

1.malloc

1.这个函数是用来向内存申请 一块连续可用的空间,并返回指向这块空间的指针

2.如果开辟成功,返回一个指向开辟好空间的指针

3.如果开辟失败,则返回一个NULL,因此malloc必须做返回值检查

4.返回类型为void*,需要自己根据需要调整

5.如果size为0,这种行为是未定义的,取决于编译器

#include <stdio.h>
int main()
{
  int *p=(int*)malloc(5*sizeof(int));
  if(p==NUL)
 {
   perror("malloc fail");
   return ;
 } 
 int i=0;
  for(i=0;i<5;i++)
  {
    *(p+i)=i+1;
  }
  for(i=0;i<5;i++)
  { 
    printf("%d ",p[i]);
  }

  free(p);//动态开辟的空间必须释放
  p=NULL;
}

2.free 

用来对动态开辟的内存空间释放和回收的

1.如果参数 ptr 指向的空间不是动态开辟的,那free函数的⾏为是未定义的。

2.如果参数 ptr 是NULL指针,则函数什么事都不做

3.必须是动态开辟空间的起始地址,所以对于动态内存申请过程中有p++这种如果在释放时只释放部分空间,这种行为是不允许的,释放应该是整体全部释放

4.free释放完空间后,需要手动将指针置为NULL 

3.calloc

1.calloc也是用来动态内存分配的

2.函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。

3.与malloc函数的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0.

4.如果我们要对动态申请的内存空间要求初始化时,就是用calloc函数

 

4.realloc 

1.有时对于动态开辟的空间 太小或者太大,我们需要做出调整,这时就用realloc函数来调整动态开辟内存大小

2.ptr是要调整的内存地址,size是调整之后新大小,返回值是调整之后的内存起始地址

3.realloc在调整内存空间的两种情况

4.当ptr为NULL时,realloc和malloc作用一样

原地扩容

异地扩容

 

使用

 

 

二:常见错误分析 

1.malloc返回值不检查直接使用

#include <stdio.h>
int main()
{
  int *p=(int*)malloc(5*sizeof(int));
  *p=20;//如果指针p为空,则直接对空指针解引用错误
   free(p);
}

正确的应该检查malloc的返回值,不为空再进行相应操作

2.对动态开辟空间的越界访问 

int main()
{
  int i = 0;
 int *p = (int *)malloc(10*sizeof(int));
 if(NULL == p)
 {
    perror("malloc fail");
    return ;
 }
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//当i是10的时候越界访问
 }
 free(p);
 return 0;
}

3.对非动态开辟空间free 

int main()
{ 
  int a=10;
  int*p=&a;
  free(p);//对非动态开辟空间进行free直接出错
  return 0;
}

4.使用free释放动态开辟内存的一部分 

int main()
{
  int *p=(int*)malloc(5*sizeof(int));
  if(p==NUL)
 {
    perror("malloc fail");
    return ;
 }
  p++;
  free(p);//这样只会释放一部分
}

5.对同一块动态内存多次释放 

void test()
 {
 int *p = (int *)malloc(100);
 free(p);
 free(p);//重复释放
 }

6.对动态内存空间未释放--内存泄漏 

int main()
{
  int *p = (int *)malloc(100);
  if(NULL != p)
   {
     *p = 20;
   }
   //未释放动态开辟空间,内存泄漏
   return 0;
}

三:柔性数组 

1.定义

结构体中最后一个成员是数组,但数组没有指定大小

struct S
{
  int n;
  int a[];//或者int a[0];
};

2.特点 

 1.结构中的柔性数组成员前⾯必须⾄少⼀个其他成员

2.sizeof 返回的这种结构⼤⼩不包括柔性数组的内存

3.包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该⼤于结构的⼤ ⼩,以适应柔性数组的预期⼤⼩

3.使用 

4.内存分配规则 

就如上面用malloc来开辟空间时,内存上为

5.非柔性数组方法 

#include <stdio.h>
#include <stdlib.h>
typedef struct st_type
{
 int i;
 int *p_a;
}type_a;

int main()
{
 type_a *p = (type_a *)malloc(sizeof(type_a));
 p->i = 100;
 p->p_a = (int *)malloc(p->i*sizeof(int));
 
 //业务处理
 for(i=0; i<100; i++)
 {
 p->p_a[i] = i;
 }
 
 //释放空间
 free(p->p_a);
 p->p_a = NULL;
  free(p);
  p=NULL;
  return 0;
}

6.柔性数组的优势 

1.方便内存释放

2.有利于提高访问速度

四:c/c++中程序内存区域划分

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值