如果没有顺序的内存空间,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` 会做啥?

在顺序栈中,如果存放元素的数组空间不足,如何增加内存空间,可以直接修改数组大小么

realloc函数详解

如果 Java 子包不提供特殊的访问关系,它们会做啥?

C++ - 如果构造函数是私有的,这会做啥?

如果构造函数中发生错误,Qt 会做啥? [复制]