总述:
内存区域可分为栈,堆,静态存储区和常量存储区,对于常见的局部变量,函数形参,临时变量都是在栈上获得内存的,它们的获取方式都是通过编译器直接执行.
而利用指针来管理内存的时候,可以更加自由的像汇编一样处理内存的地址, C 标准函数库提供了很多函数来实现对堆上内存的管理,从开辟内存空间到释放内存空间都有相应的函数,这些函数都包含在头文件 stdlib.h 中,其中有几个特别重要的函数需要做区分和了解,它们分别是: malloc、alloc、calloc、realloc 以及 free,而对 malloc 和 free 的具体内容分析请移步C语言 malloc 和 free.这些函数之间的细微差别在于对内存的管理的细节和操作不同.
从函数名的字面上理解:这几个函数都带 alloc 也就是 allocate ,分配的意思. calloc() 是”分配内存给多个对象”, malloc() 是”分配内存给一个对象”, realloc() 是”重新分配内存”.
泛泛理解
calloc()
void *calloc(size_t nobj, size_t size);
分配足够的内存给nobj个大小为size的对象组成的数组,并返回指向所分配区域的第一个字节的指针;
若内存不够,则返回NULL.该空间的初始化大小为0字节.
举例:
char *p = (char *) calloc(100,sizeof(char));
malloc()
void *malloc(size_t size);
分配足够的内存给大小为size的对象,并返回指向所分配区域的第一个字节的指针;
若内存不够,则返回NULL.不对分配的空间进行初始化.
举例:
char *p = (char *)malloc(sizeof(char));
realloc()
void *realloc(void *p, size_t size);
将p所指向的对象的大小改为size个字节.
如果新分配的内存比原内存大,那么原内存的内容保持不变,增加的空间不进行初始化.
如果新分配的内存比原内存小,那么新内存保持原内存的内容,增加的空间不进行初始化.
返回指向新分配空间的指针;若内存不够,则返回NULL,原p指向的内存区不变.
举列:
char *p = (char *)malloc(sizeof(char));
p = (char *)realloc(p, 256);
alloc()
alloc 的调用序列与 malloc 相同,与 malloc 不同的是 alloc 在当前的函数的栈帧上分配存储空间,而不是在堆中.这样做的好处是:函数返回时,自动释放它所使用的栈帧,所以不必再为释放空间而费心.也就是说不必要担心操作它的释放问题.同样这样处理的其缺点也很明显:某些系统在函数已被调用后不能增加栈帧长度,于是也就不能支持 alloc 函数.尽管如此,很多软件包还是使用 alloc 函数,也有很多系统支持它.
注意事项:
通过 malloc 函数得到的堆内存必须是要由 memset 函数来初始化的.
malloc函数分配得到的内存空间是未初始化的,因此,一般在使用该内存空间时,要调用另一个函数 memset 来将其初始化为全0, memset 函数的声明如下: void memset (void p,int c,int n);
举例:
int * p = NULL;
p=(int *)malloc(sizeof(int));
if(p==NULL)
printf(“Can’t get memory!\n”);
memset(p,0,siezeof(int));
使用 malloc 函数分匹配空间堆空间在程序结束之前必须释放.
从堆上获得的内存空间在程序结束以后,系统不会将其自动释放,需要程序员来自己管理.一个程序结束时,必须保证所有从堆上获得的内存空间已被安全释放,否则,会导致内存泄露.
可以用 free 函数来释放.calloc函数的分配的内存也需要自行释放.
calloc 函数的功能与 malloc 函数的功能相似,都是从堆分配内存,它与 malloc 函数的一个显著不同时是, calloc 函数得到的内存空间是经过初始化的,其内容全为0. calloc 函数适合为数组申请空间,可以将 size 设置为数组元素的空间长度,将 n 设置为数组的容量.
如果要使用 realloc 函数分配的内存,必须使用 memset 函数对其内存初始化.
realloc 函数的功能比 malloc 函数和 calloc 函数的功能更强大,可以实现内存分配和内存释放的功能. realloc 可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变.其中对于缩小来说,则被缩小的那一部分的内容会丢失. realloc 并不保证调整后的内存空间和原来的内存空间保持同一内存地址.相反 realloc 返回的指针很可能指向一个新的地址.
举例:
p = (int *) realloc(p, sizeof(int) *15); //必须将realloc返回的值,重新赋给P int* p = (int *) realloc(0,sizeof(int) * 10); //分配一个全新的内存空间,因为当传一个空指针(0)给realloc时,此时的realloc的作用完全等同于malloc. 完全等同于:int* p = (int *)malloc(sizeof(int) * 10);