【发布时间】:2011-04-10 16:51:17
【问题描述】:
realloc用于动态重新分配内存。
假设我使用 malloc 函数分配了 7 个字节,现在我想将其扩展为 30 个字节。
如果内存中没有连续(连续单行)的 30 字节空间,后台会发生什么?
是否有任何错误或将部分分配内存?
【问题讨论】:
标签: c dynamic-memory-allocation realloc
realloc用于动态重新分配内存。
假设我使用 malloc 函数分配了 7 个字节,现在我想将其扩展为 30 个字节。
如果内存中没有连续(连续单行)的 30 字节空间,后台会发生什么?
是否有任何错误或将部分分配内存?
【问题讨论】:
标签: c dynamic-memory-allocation realloc
FreeBSD 和 Mac OS X 具有 reallocf() 函数,当请求的内存无法分配时,该函数将释放传递的指针(参见 man realloc)。
【讨论】:
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 适用于所有实现吗?
realloc 的可观察行为。
一般来说,这取决于实现。在 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。
【讨论】:
来自man page:
realloc() 返回一个指向 新分配的内存,即 适合任何类型的对齐 变量并且可能不同于 ptr,如果请求失败,则为 NULL。
也就是说,要检测失败,只需检查结果是否为NULL。
编辑:如评论中所述,如果调用失败,则不会释放原始内存。
【讨论】:
realloc 只有在它可以返回一个连续的(用你的话来说是“顺序的”)内存块时才会成功。如果不存在这样的块,它将返回NULL。
【讨论】:
if (!x) exit(1); 关注它,这不是错误:-)