【问题标题】:Also check realloc() if shrinking allocated size of memory?如果缩小分配的内存大小,还要检查 realloc() 吗?
【发布时间】:2014-04-04 02:28:55
【问题描述】:

当你调用realloc()时,你应该在将返回的指针分配给作为参数传递给函数的指针之前检查函数是否失败......

我一直遵守这条规则。

现在,当您确定内存将被截断而不是增加时,是否有必要遵循此规则?

我从未见过它失败。只是想知道我是否可以保存一些说明。

【问题讨论】:

  • 考虑一下,如果实现发现您的较小分配可能驻留在内存中的其他位置怎么办? (特别是当内存有些碎片化时)在这种情况下,实现不需要返回相同的内存位置。
  • @JeffMercado - 我看不出所提问题与您的评论之间有什么关系。问题是 realloc() 操作在这种情况下会失败吗?
  • @martinkunev:问题是询问是否有必要测试是否应该测试会使块更小的realloc() 调用。答案是肯定的。实现可以自行决定尝试分配一个新块并将项目移动到该块。新分配可能会失败,因此必须检查。我评论的最后一点指出,假设收缩操作总是返回相同的块是不正确的。

标签: c++ c realloc


【解决方案1】:

realloc 可以自行决定将块复制到新地址,无论新大小是更大还是更小。如果malloc 实现需要新分配来“缩小”内存块(例如,如果新大小需要将内存块放在不同的分配池中),这可能是必要的。这在glibc documentation 中注明:

在几种分配实现中,有时需要将块变小以复制它,因此如果没有其他可用空间,它可能会失败。

因此,您必须始终检查realloc 的结果,即使在缩小时也是如此。 realloc 可能未能收缩块,因为它不能同时分配一个新的更小的块。

【讨论】:

    【解决方案2】:

    即使您将realloc(请仔细阅读realloc(3) 和有关Posix realloc)缩小到更小的尺寸,底层实现也相当于malloc(新的更小的尺寸),然后是memcpy(从旧区到新区),然后是free(旧区)。或者它可能什么都不做......(例如,因为一些粗略的malloc 实现维护了一组有限的尺寸——比如 2 的幂或 2 的 3 倍的幂——并且新旧尺寸要求适合相同的尺寸。 ..)

    malloc 可能会失败。所以realloc 仍然会失败。

    实际上,出于这个原因,我通常不建议使用realloc:只需自己使用mallocmemcpyfree

    确实,像malloc 这样的动态堆内存函数很少会失败。但是当他们这样做时,如果你不处理它,可能会发生混乱。在 Linux 和其他一些 Posix 系统上,您可以使用 setrlimit(2)RLIMIT_AS -e.g.使用 bash ulimit builtin- 降低测试限制。

    您可能想研究C memory management 的源代码实现。例如MUSL libc(对于 Linux)是非常易读的代码。在 Linux 上,malloc 通常构建在 mmap(2) 之上(C 库可能会使用 mmap 分配一大块内存,然后在其中管理较小的已用和已释放内存区域)。

    【讨论】:

    猜你喜欢
    • 2016-07-04
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 2019-08-04
    • 2021-12-23
    • 2019-07-20
    • 2014-05-18
    相关资源
    最近更新 更多