①要想使用malloc,calloc,realloc,free须先引入stdlib.h头文件
malloc是向堆区申请一块指定大小的连续内存空间,成功的话返回空间的首地址(保存好malloc开辟的首地址,不要改变其首地址),失败的话返回一个空指针。
free用来释放内存空间(通过malloc,calloc,realloc获得的动态内存空间),只能释放一次(空指针可以被释放多次)。
分配成功后如果空间被free之后,任然能够通过指向改变其值,所以在free之后要紧接着置指针为NULL
calloc与malloc的区别是calloc申请空间后会把空间内容初始化为00000000
realloc在原有分配空间基础上增加或减少空间。
堆区:程序运行时可以在堆区动态地请求一定大小的内存,并在用完之后归还给堆区。
int main()
{
int *p = NULL;
int *p1 = NULL;
p = (int*)malloc(sizeof(int)*5);//开辟5个连续空间
p1 = (int*)malloc(sizeof(int)*5);
int *ip = p1;
if(NULL == p)//必须有
{
exit(1);//开辟空间失败,终止当前程序的执行,
}
for(int i=0;i<5;i++)
{
p[i]=i;
}
free(p);//释放p指向的空间,将其还给堆区,这是p还指向该空间。
p = NULL;//防止失效指针对内存造成伤害
//free和置空NULL这两步必须可少
free(ip);//也是一种释放空间的方式
p1 = NULL;
ip = NULL;
return 0;
}
②动态开辟二维数组(注意释放空间时的顺序)
int main()
{
int **s = NULL;//4行5列
s = (int**)malloc(sizeof(int*)*4);//s里面存放的时一级指针,所以s为二级指针
//4行
if(NULL == s)
{
exit(1);
}
for(int i = 0;i < 4;i++)
{
s[i]=(int*)malloc(sizeof(int)*5);//5列
}
for(int i=0;i<4;i++)
{
for(int j=0;j<5;j++)
{
s[i][j]=i+j;
printf("%d\t",s[i][j]);
}
printf("\n");
}
for(int i=0;i<4;i++)
{
free(s[i]); //先释放
s[i] = NULL;
}
free(s); //释放s指向的空间
s = NULL;
return 0;
}
③realloc表示在原有的基础上面进行追加,扩充到n个某类型空间。
有三种扩充方案:
①后续未分配内存空间足够大,可以分配空间。
②后续未分配内存空间不足够大,不能分配空间,这时就会在新的地址分配空间,把原来空间释放掉。
③堆内存不足,扩展空间失败,realloc函数返回NULL,这种情况会导致数据丢失,内存泄漏。
int main()
{
int n = 5,m = 10;
int *p = NULL;
p=(int*)malloc(sizeof(int)*n);
if(NULL == p)
{
exit(1);
}
for(int i = 0;i < n;i++)
{
p[i] = i;
}
int *s=(int*)realloc(p,sizeof(int)*m);//防止扩充空间失败,出现数据丢失,内存泄漏等情况
//扩充后s指向的空间时m*(sizeof(int))==40个字节空间。
if(NULL != s)
{
p = s;
}
else
{
printf("追加空间失败\n");
}
free(p);
p = NULL;
free(s);
s = NULL;
return 0;
}