如果正在缩小已分配的内存大小,请同时检查realloc()

Also check realloc() if shrinking allocated size of memory?

本文关键字:检查 realloc 缩小 分配 内存 如果      更新时间:2023-10-16

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

我一直遵循这个规则。

现在,当你确信内存将被截断而不是增加时,有必要遵循这个规则吗?

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

realloc可以自行决定将块复制到新地址,无论新大小是大是小。如果malloc实现需要新的分配来"收缩"内存块(例如,如果新的大小需要将内存块放置在不同的分配池中),则这可能是必要的。这在glibc文档中有说明:

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

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

即使您将realloc(请仔细阅读realloc(3)和关于Posix realloc的内容)设置为较小的大小,底层实现也相当于malloc(新的较小大小),然后是memcpy(从旧区域到新区域),然后free(旧区域)。或者它可能什么都没做。。。(例如,因为一些粗略的malloc实现可能具有一组有限的大小,如二次幂或三倍二次幂,并且旧的和新的大小要求适合相同的大小……)

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

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

事实上,像malloc这样的动态堆内存函数很少失败。但当他们这样做的时候,如果你不处理,混乱可能会发生。在Linux和其他一些Posix系统上,您可以使用RLIMIT_AS设置rlimit(2),例如使用内置的bashulimit,以降低测试限制。

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