【发布时间】:2016-02-12 11:11:06
【问题描述】:
C++ 中没有realloc;当然你总是可以用new分配一个新块,把旧块复制到新块,用delete释放旧块。
问题是 realloc 通常可以比这更快——这发生在内存块“就地”重新调整大小时——即realloc 的返回值恰好与参数指针值相同;这也避免了将内存从旧块复制到新块。
标准说什么 - 是否允许将全局 new 运算符返回的指针传递给 realloc? (在 glibc 中,new 和 malloc 都使用相同的分配器,所以这里应该不存在实际问题)。 C++ 标准对这个问题有什么要说的吗?
(当前的 glibc 标准 C++ 库不执行 realloc,即使在向量中也是如此 - 因为一旦分配了对象,运行时就无法在旧内存块上调用析构函数并在新块上调用放置 new -如果内存块已经被realloc 移动了。如果标准库有一个不能将参数块移动到新位置的就地realloc 会更简单)
编辑:
实际上有些内存分配器有一个就地的realloc 函数;这些当然是非标准的。
-
jemalloc 有一个名为
rallocm的 API,带有标志ALLOCM_NO_MOVE -
dlmalloc (Doug Lea malloc) 有一个名为
dlrealloc_in_place的 API
如果您将 jemalloc 或 dlmalloc 用于全局运算符 new 和 delete,那么您可以将这些非标准函数用于矢量类,该类在执行移动 malloc 之前尝试就地 realloc 进行复制.或者可以请求 C++ 标准委员会在标准中添加一种全局非移动重新分配方法。
编辑:
或者你可以做一个向量类,其中内存管理是通过malloc/realloc/free 完成的,但是这个实现只能在元素类型是普通旧数据时实例化(即如果std::is_pod返回向量所持有的类型为真)。
【问题讨论】:
-
realloc只能用于由malloc、calloc或realloc分配的指针。 -
让标准库实现者担心这些东西。如果有更快的方法来增长向量,可以肯定地假设他们会找到并使用它。
-
我尝试并未能将类似 realloc 的功能置于向量的底层:open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1953.html
-
我把它带到 C 委员会试图驯服 realloc:open-std.org/jtc1/sc22/wg14/www/docs/n1085.htm 那也失败了。
标签: c++ dynamic-memory-allocation