realloc
用于动态重新分配内存。
假设我使用该malloc
函数分配了 7 个字节,现在我想将其扩展为 30 个字节。
如果内存中没有 30 字节的连续(单行连续)空间,后台会发生什么?
是否有任何错误或将部分分配内存?
realloc
用于动态重新分配内存。
假设我使用该malloc
函数分配了 7 个字节,现在我想将其扩展为 30 个字节。
如果内存中没有 30 字节的连续(单行连续)空间,后台会发生什么?
是否有任何错误或将部分分配内存?
realloc
幕后工作大致是这样的:
NULL
。因此,您可以通过测试来测试失败NULL
,但请注意不要过早覆盖旧指针:
int* p = malloc(x);
/* ... */
p = realloc(p, y); /* WRONG: Old pointer lost if realloc fails: memory leak! */
/* Correct way: */
{
int* temp = realloc(p, y);
if (NULL == temp)
{
/* Handle error; p is still valid */
}
else
{
/* p now possibly points to deallocated memory. Overwrite it with the pointer
to the new block, to start using that */
p = temp;
}
}
realloc
只有当它可以返回一个连续的(用你的话来说是“顺序的”)内存块时,它才会成功。如果不存在这样的块,它将返回NULL
.
从手册页:
realloc() 返回一个指向新分配内存的指针,该指针适合任何类型的变量对齐,并且可能与 ptr 不同,如果请求失败,则返回 NULL。
所以换句话说,要检测失败,只需检查结果是否为NULL。
编辑:如评论中所述,如果调用失败,则不会释放原始内存。
一般来说,这取决于实现。在 x86(-64) Linux 上,我相信标准 doug lea malloc 算法将始终分配至少一个标准 x86 页面(4096 字节),因此对于您上面描述的场景,它只会重置边界以容纳额外的字节。比如说,将 7 字节的缓冲区重新分配给 PAGE_SIZE+1,我相信它会尝试分配下一个连续页面(如果可用)。
如果您在 Linux 上开发,值得阅读以下内容:
默认情况下,Linux 遵循乐观的内存分配策略。这意味着当 malloc() 返回非 NULL 时,不能保证内存确实可用。这是一个非常糟糕的错误。如果发现系统内存不足,一个或多个进程将被臭名昭著的 OOM 杀手杀死。如果在不希望突然丢失一些随机选择的进程的情况下使用 Linux,并且内核版本足够新,则可以使用以下命令关闭这种过度使用行为:
# echo 2 > /proc/sys/vm/overcommit_memory
另请参阅内核文档目录、文件 vm/overcommit-accounting 和 sysctl/vm.txt。
FreeBSD 和 Mac OS X 具有 reallocf() 函数,当请求的内存无法分配时,该函数将释放传递的指针(参见 man realloc)。