malloc,calloc,realloc的理解

来源:互联网 发布:洞主卖香皂的淘宝店 编辑:程序博客网 时间:2024/06/05 19:38
三个函数的申明分别是:
void* realloc(void* ptr, unsigned newsize);
void* malloc(unsigned size);
void* calloc(size_t numElements, size_t sizeOfElement);
都在stdlib.h函数库内

它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL

malloc用于申请一段新的地址,参数size为需要内存空间的长度,如:
char* p;
p=(char*)malloc(20);

calloc与malloc相似,参数sizeOfElement为申请地址的单位元素长度,numElements为元素个数,如:
char* p;
p=(char*)calloc(20,sizeof(char));
这个例子与上一个效果相同

realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度
如:
char* p;
p=(char*)malloc(sizeof(char)*20);
p=(char*)realloc(p,sizeof(char)*40);

注意,这里的空间长度都是以字节为单位。


这里重点说下realloc:

realloc 用过很多次了。无非就是将已经存在的一块内存扩大。

char* p = malloc(1024);
char* q = realloc(p,2048);

现在的问题是我们应该如何处理指针 p。 刚开始按照我最直观的理解,如果就是直接将 p = NULL;。 到最后只需要释放 q的空间就可以了。

因为最近在做个封装。结果在做单元测试的时候发现。有时候我在 free(q); 的时候会出错。这样我就郁闷了。

后来仔细一跟踪,发现 realloc 完以后 q 和 p 的指针地址是一样。不过有时候又不一样。

仔细查了下资料。得到如下信息:

       1.如果 当前连续内存块足够 realloc 的话,只是将p所指向的空间扩大,并返回p的指针地址。 这个时候 q 和 p 指向的地址是一样的。

       2.如果 当前连续内存块不够长度,再找一个足够长的地方,分配一块新的内存,q,并将 p指向的内容 copy到 q,返回 q。并将p所指向的内存空间删除。

这样也就是说 realloc 有时候会产生一个新的内存地址 有的时候不会。所以在分配完成后。我们需要判断下 p 是否等于 q。并做相应的处理。

这里有点要注意的是要避免 p = realloc(p,2048); 这种写法。有可能会造成 realloc 分配失败后,p原先所指向的内存地址丢失。

 

我的话:其实在这里我们不需要处理p(指无需释放内存),为什么呢?

按照msdn上的说法,函数在调用的时候会出现三种情况,接下来我重点说这三种情况:

1. 成功在其后增加指定的空间,这种情况是不需要处理p的,因为p==q

2. 指定其后分配的空间不足,从而从新分配和赋值.q的内存其实已经帮我们释放了.我们更没有理由去管它.

3. 系统分配失败,将保持原来的大小不变.这是我们只要判断p是否为空即可.