calloc,malloc,realloc 的理解

来源:互联网 发布:手机本机mac地址查询 编辑:程序博客网 时间:2024/06/05 15:56

结合网上一些质料和帮助文档,谈谈对内存管理的几个函数理解:


calloc():分配内存给多个对象。cleared allocate, 分配后会把内存区初始化为0。适合为数组申请空间。

mallco():分配内存给多个一个对象。分配后需要用memset()初始化内存。

realloc():再分配。分配后需要用memset()初始化内存。

**都在<stdlib.h>头文件内。

 

(1)void * calloc (size_t num, size_t size)

分配给num个, 大小为size的对象组成的数组。返回并指向分配区得第一个字节的指针。若内存不够,则返回NULL,该空间初始化大小为0字节。

char *p = (char *) calloc (100,sizeof(char));

 

(2)void * realloc(void *p ,size_t size)

       将p指向的对象的大小改为size个字节。

       如果新分配的内存比原来的内存大,那么原内存的内容保持不变,增加空间不初始化。

如果新分配的内存比原来的内存小,那么新内存保持原内存的内容,被缩小的那部分会被丢失。

       下图是我的理解,红色为新(pTmp)所指,蓝色为旧(pOrig)所指。

       1.新分配的比旧的内存小,那么把新内存保持有原来内存的内容,被缩小的那部分相当于释放掉。旧指针和新指针指向相同的区域(即pTmp == pOrig),所以释放内存的时候可以用pTmp或者pOrig来释放内存。

       2.新区比旧区大,不过新区是直接从堆上现存的数据后面的那些字节中获得附加的字节,所以旧指针和新指针指向相同的区域(即pTmp == pOrig),所以释放内存的时候可以用pTmp或者pOrig来释放内存。

       3.新区比旧区大,但是新区数据后面的字节不够的话,就使用堆上第一个有足够大小的自由块,现存的数据然后就被拷贝至新的位置,而老块则放回到堆上(相当于把旧区的内存释放掉),这是旧指针已经无法再获取原来内存的数据。

     

       所以,在代码中,我们必须将realloc返回的值,重新赋值给 p :

    p = (int *) realloc(p, sizeof(int) *15);

       甚至,你可以传一个空指针(0)给 realloc ,则此时realloc 作用完全相当于malloc。

       int* p = (int *)realloc (0,sizeof(int) * 10);   //分配一个全新的内存空间,

       这一行,作用完全等同于:

       int* p = (int *)malloc(sizeof(int) * 10)

 

程序步骤:

       1.分配成功,返回void*指针:realloc返回值如果与前面malloc的值不同,那么realloc函数完成后,pOrig指向的旧内存自动free掉。
       2.分配失败,返回NULL值:此时,原来指向的内存还没有被free掉,而现在又找不到地址,这样就出现memory leak了。 

       解决办法:定义另一个指针pTmp用于接收realloc返回值,判断是否成功,成功则将pTmp赋给pOrig.

pTmp = realloc(pOrig, new_size);
if (pTmp == NULL) {
        free(pOrig);
        return;
}

pOrig = pTmp;

pTmp = NULL;

 

(3)void *mallco(size_t size):

int * p = NULL;
p = (int *)malloc(sizeof(int)); //

if( p == NULL) //要判断是否内存分配成功。

{

       printf(“Can’t get memory !\n”);

}

memset(p,0,sizeof(int));  //用0来初始化。

 

free(p);//释放p所指的空间。

p = NULL;//防止野指针。