c/c++ 内存动态分配与回收
c语言提供内存的动态分配的函数有:
malloc,calloc,realloc。在使用这些函数时,必须包含其头文件,分别为:<malloc.h>,<stdlib.h>,<alloc.h>
1.malloc函数
malloc函数原型: void *malloc(unsigned int size)
作用:在内存的动态分配区域中分配一个长度为size的连续空间。
类型说明符:void说明该函数适用与任意的数据类型。
参数:size为无符号整型数。
返回值:如果分配成功,则返回所分配内存空间的首地址。如果失败,则返回NULL。
注:申请的内存不会进行初始化。
例子:
char *p = (char *)malloc(sizeof(char)*10);
//申请了10个char长度的空间,但并不知道是否申请成功。
if(NULL == p)
{
return;//申请内存空间失败
}
2.calloc函数
calloc函数原型:void *calloc(unsigned int num,unsigned int size)
作用:按照所给的数据个数和数据类型所占字节数,分配一个num*size连续的空间。
类型说明符:void说明该函数适用与任意的数据类型。
参数:num:无符号整数,表示要分配的个数。size:无符号整型数,表示该数据类型所占字节数。
返回值:如果分配成功,则返回内存空间的首地址,如果失败,则返回NULL。
与malloc函数区别:
calloc申请完内存空间后,会自动初始化内存空间为0。但是malloc不会进行初始化,起内存空间存储的是一些随机数据。
例子:
char *p = (char *)calloc(10,sizeof(char));
//申请了10个char长度的内存空间
if(NULL == p)
{
return;//申请内存空间失败
}
3.realloc函数
realloc函数原型:void *realloc(void *ptr,unsigned int size)
作用:动态分配一个长度为size的内存空间,并把该内存空间的首地址赋值给ptr。把ptr所指的内存空间大小调整为size。
参数:ptr:指向一个内存空间的指针。size:需要的申请的内存空间大小。
返回值:如果分配成功,则返回内存空间的首地址,如果失败,则返回NULL。
注意:
申请的内存空间不会进行初始化。
如果有足够空间用于扩大ptr指向的内存块,则分配额外内存,并返回ptr。这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= size。那么就ok。得到的是一块连续的内存。
如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块size大小的内存。并把原来大小内存空间中的内容复制到size中,返回新的ptr指针。(数据被移动了)。老块被放回堆上。
返回值。返回一个void类型指针,则分配成功。如果返回值为NULL,size=0,但是ptr!=NULL,那么原内存就丢失了。如果返回值为NULL,没有可用的内存,那么ptr所指向的内存空间不变。
特殊情况。如果ptr=NULL,size=0,
例子:
char *p = (char *)malloc(10);
//char *p = "12345";如果使用此语句,执行realloc时会发生错误
char *q = p;
p = (char *)realloc(p,100);//如果在p原来指向的内存后面没有足够的内存空间来扩展,那么先前分配的10个字节的内存空间被丢弃,即q指针变成了野指针
p[0] = '0';
p = (char *)realloc(p,0);
cout<<p[0]<<endl;//此语句运行时会产生错误:非法访问内存。
在使用c语言提供的这些动态内存分配函数后,对于这些已经申请的内存空间需要你自己进行释放。如果你没有释放,并且你只是随便运行一下自己的一个很小的程序,可能不会产生什么很大的影响。但是,如果这样一个大型程序或软件运行中调用了这些语句,而没有对申请的内存进行释放,那么后果是很严重的。
因此,在我们平时写程序的过程中,应该养成好的变成习惯。在使用了这些函数动态分配了一段内存后,要记得对其进行释放。
释放的函数为free函数:
free函数原型为:void free(void *ptr)
作用:释放由上面3种函数所申请的内存空间。
参数:ptr:指向需要释放的内存空间的首地址。
例子:
char *p = (char *)calloc(10,sizeof(char));
//申请了10个char长度的内存空间
if(NULL == p)
{
return;//申请内存空间失败
}
...
free(ptr);//释放申请的内存空间