如果没有顺序的内存空间,realloc 会做啥?
Posted
技术标签:
【中文标题】如果没有顺序的内存空间,realloc 会做啥?【英文标题】:What would realloc do if there is no sequential space of memory?如果没有顺序的内存空间,realloc 会做什么? 【发布时间】:2011-04-10 16:51:17 【问题描述】:realloc
用于动态重新分配内存。
假设我使用 malloc
函数分配了 7 个字节,现在我想将其扩展为 30 个字节。
如果内存中没有连续(连续单行)的 30 字节空间,后台会发生什么?
是否有任何错误或将部分分配内存?
【问题讨论】:
【参考方案1】:FreeBSD 和 Mac OS X 具有 reallocf() 函数,当请求的内存无法分配时,该函数将释放传递的指针(参见 man realloc)。
【讨论】:
如果你真的想要这种行为,那么编写自己的函数来这样做会更有意义,而不是使用它。但我无法想象它非常有用 - 它会丢弃可能有价值的数据。【参考方案2】: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
适用于所有实现吗?
@CoolGuy:某些实现可能无法(能够)执行扩展当前块的第一步,但除此之外,这是所有实现realloc
的可观察行为。【参考方案3】:
一般来说,这取决于实现。在 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。
【讨论】:
【参考方案4】:来自man page:
realloc() 返回一个指向 新分配的内存,即 适合任何类型的对齐 变量并且可能不同于 ptr,如果请求失败,则为 NULL。
也就是说,要检测失败,只需检查结果是否为NULL。
编辑:如评论中所述,如果调用失败,则不会释放原始内存。
【讨论】:
值得从手册页中注意:如果 realloc() 失败,则原始块保持不变;它没有被释放或移动。【参考方案5】:realloc
只有在它可以返回一个连续的(用你的话来说是“顺序的”)内存块时才会成功。如果不存在这样的块,它将返回NULL
。
【讨论】:
@Mark - 原始内存保持不变。这种情况下的一个常见错误是 'x=realloc(x)' - 您必须执行 'newX=realloc(x)' 以避免在错误时泄漏原始 x。 @Steve Townsend - 只有在仪式失败的情况下?成功后,它会释放原始指针。这个页面上的马克是谁? O_o 我猜有一个错误。第一条评论来自用户 sharptooth,现在它已更改,尽管两者都是针对 Mark 的。那是一个错误吗? :-P @Praveen - 我的评论是针对一个现已删除的早期评论。是的,我展示的用法仍然是一个错误。成功后,它会释放原始指针(如果可以将连续的较大块锚定在那里,则将其返回给您再次使用)。 @Steve:如果您使用if (!x) exit(1);
关注它,这不是错误:-)以上是关于如果没有顺序的内存空间,realloc 会做啥?的主要内容,如果未能解决你的问题,请参考以下文章
如果 file.txt 没有暂存,`git commit file.txt` 会做啥?