【发布时间】:2021-12-31 22:59:02
【问题描述】:
realloc 可能只是在这里和那里更新簿记信息以增加您的分配大小,或者实际上可能malloc 一个新的和memcpy 以前的分配(或可能失败)。
我希望能够查询内存管理器,如果分配是可调整大小的(可能是因为它保留的比我mallocd 多,或者因为它能够合并相邻的块,等等。 .) 如果是,那么我会要求它继续这样做,否则我想自己以任意顺序将原始分配的任意子集 malloc 和 memcpy。
其他 StackOverflow 答案似乎是这四个之一:
- 无论如何建议
realloc。对于大量数据,这可能效率很低,在这种情况下,双重复制可能会产生严重影响。通常,这是最快的便携路线。 - 建议手动
malloc+memcpy+free。这更糟,因为现在不是 some 在分配可能无法调整大小时进行双重复制,而是在每次分配填满时 everything 被双重复制。表现非常糟糕。 - 建议一个特定于平台的扩展。这是不切实际的,因为我的代码和很多 C 代码一样,需要可移植性。
- 暗示这是不可能的。 C 已经假设存在一个内存管理器,它能够在适当的位置调整分配的大小或创建一个新的。那么,为什么我不能对它进行更高级别的控制呢?我们可以对齐malloc;为什么不是这个?
注意:这个问题同时发布在 C 和 C++ 标记下,因为任何一种语言的解决方案都是可接受且相关的。
编辑 1:
用FB向量的话来说:
但是等等,还有更多。许多内存分配器不支持就地重新分配,尽管大多数都可以。这来自现在臭名昭著的 realloc() 设计,以不透明地执行就地重新分配或 allocate-memcpy-deallocate 循环。这种缺乏控制随后迫使所有基于 clib 的分配器设计避免就地重新分配,其中包括 C++ 的 new 和 std::allocator。这是效率的重大损失,因为非常便宜的就地重新分配可能意味着不那么激进的增长战略。反过来,这意味着更少的闲置内存和更快的重新分配。
见this。
【问题讨论】:
-
没有标准或可移植的方式来做到这一点。在这种情况下,这可能就是“不可能”所指的。并不是说它在技术上是不可能实现的。只是 C 规范没有指定,因此没有非标准扩展是不可能的。
-
@kaylum WG14 是否愿意接受这样的建议?还是 libc 不是他们当前的重点?
-
您的列表似乎正确且详尽。你的问题到底是什么?
-
如果您需要自定义语义,建议您编写自己的分配器。你分配了多少内存?我无法想象像大块内存的副本要花那么长时间。我看到quora.com/… 在我的电脑上复制 1GB 需要 0.15 秒,这不算多,你不会经常重新分配。
-
对于非平凡的可重新分配情况,您为什么更愿意手动使用
malloc和memcpy?为什么不让realloc为你做呢? “双重复制”是什么意思?应该只执行一份副本。此外,虽然复制可能既昂贵又糟糕,但大多数人并不在意,因为它通常会通过以指数方式增长缓冲区来分期偿付。
标签: c++ c memory-management realloc