本次将分享 C 中的动态内存管理。C 语言为内存的分配和管理提供了几个分配空
间函数 malloc,calloc,realloc,还有释放内存的函数 free。
需要包含的头文件:
#include<stdlib.h>
malloc 和 calloc 的区别
malloc 的函数原型是:
void *malloc(int num);
意思为在堆上分配一段字节大小为 num
的空间返回返回空间的地址。当被分配的空间没有被使用过时,空间中的值可能都是 0
,但是如果空间被使用过,可能会遗留一些数据,那么 malloc
分配的空间不会对此置零,那我们来看
calloc,
它的函数原型是
void *calloc(int num,int size);
意思为在堆中动态地分配 num
个长度为
size
的连续空间,并将每一个字节都初始化为 0
。所以它的结果是分配了
num*size
个字节长度的内存空间,并且每个字节的值都是 0。
所以两者的就在于参数不同还有是否会对其进行初始化的区别了
realloc
该函数重新分配内存
,
一般用于扩展内存,函数原型是:
void *realloc(void *address, int newsize);
address 是你动态分配的地址,newsize 是你扩充后的大小:
如果是将分配的内存扩大,则有以下情况:
1)如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。
2)如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一 要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的
内存块位置。
3)如果申请失败,将返回 NULL,此时,原来的指针仍然有效。
使用时
注意
的点:
1
.
如果调用成功,不管当前内存段后面的空闲空间是否满足要求,都会释放掉原来的指针,重新返回一个指针,虽然返回的指针有可能和原来的指针一样,即不能再次释放掉原来的指针。
int *p = (int *)malloc(100);
realloc(p,200);
printf("%d\n",*p); //p 被释放,继续访问将产生段错误
free(p); //p 被释放,继续 free 将产生段错误
当使用 realloc
对
p
重新定义大小后,在
realloc
内部其实已经做了
free(p)
的操作,那么继续使用 p
和
free
将可能引发段错误,所以
,
我们应该重新定义一个指针去接受 realloc
返回的新地址。
2
.
不要将返回结果再赋值给待分配的指针,即
ptr=realloc(ptr,new_size)
是不建议使用的,因为如果内存分配失败,ptr
会变为
NULL
,如果之前没有将
ptr
所在地址赋给其他值的话,会发生无法访问旧内存空间的情况,所以建议使用temp=realloc(ptr,new_size)
3
.
重新分配的空间如果小于原来的空间,只有重新分配空间大小的数据会被保存,可能会发生数据丢失,慎重使用。
4
. address
必须为
NULL
,或者为
malloc
,
realloc
或者
calloc
的返回值,否则发生realloc invalid pointer 错误
,
也就是只能对程序员自己申请的空间进行扩充或缩小。