众所周知,realloc()
的作用就是将已经 malloc 的内存块,重新扩展加长。当你并没有使用高端的内存池的时候,临时从堆中申请加大内存,这是很有用的。但是如何正确地使用 realloc() 呢?
Reference
调用方法
函数原型
#include <stdlib.h>
void *realloc(void *ptr, size_t size);
传入参数:
(1)需要被扩展大小的内存指针
(2)扩展后的大小(注意不是添加的大小)
返回参数:
新的指针
正确的调用方式
长篇大论放后面,我们先上代码:
uint8_t *pMemToBeRealloc = malloc(1024);
size_t memSize = 1024;
...
/* start realloc */
uint8_t *pMemBackup = pMemToBeRealloc; /* 将 realloc 之前的内存地址备份一下 */
pMemToBeRealloc = realloc(pMemToBeRealloc, 2048);
if (pMemToBeRealloc) { /* realloc 成功 */
LOG_DEBUG("Memory had been extent to 2048.");
pMemBackup = NULL;
memSize = 2048;
}
else { /* realloc 失败了,这个时候返回的是 NULL */
LOG_ERROR("Oh no, realloc() failed: %s.", strerror(errno));
pMemToBeRealloc = pMemBackup;
memSize = 1024;
}
...
原理
当 realloc()
返回 NULL 的时候,表示内存扩展动作失败了。但这个时候,原来的内存并没有被释放
,所以有必要把原来的内存预先备份下来。至于失败的时候要怎么处理,那就是程序员自己的事情了,这没有标准方案。
当 realloc()
返回非零值时呢,表示realloc是成功的。此时不论返回值是多少,程序都不需要对原来的内存地址值作特殊操作
。
为什么这么说呢?主要是参考资料里面没有把一个问题说清楚:
- 首先,如果
pMemToBeRealloc == pMemBackup
的情况,那说明只是在原来的内存基础上往后扩展就好了,这是最简单的情况 - 可是如果
pMemToBeRealloc != pMemBackup
呢?这很容易让人误解为,需要调用一次 free(pMemBackup)。这是错误的,因为这个动作,realloc 会自动帮你做了,不要画蛇添足!
BTW
,个人还建议注意一个地方:从 man 手册上面看,虽然对于 malloc() 返回的内存,大部分标准库会初始化为全零,但是对于 realloc() 扩展的部分,则不一定。
不过保险起见,应该是对于 malloc() 和 realloc() 返回的内存内容,都不要相信它们都已经被初始化为0
才好。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。