C++中的Realloc等价物

Mic*_*rst 6 c++ dynamic-memory-allocation

是的,另一种realloc与std::vector问题.我知道你要说什么,我同意,忘记手动内存分配,只需使用一个std::vector.不幸的是,我的教授禁止我使用STL的任何东西进行这项任务.

所以,是的,我有一个动态数组,T我需要它可以调整大小,我不能使用std::vector.我可以回到黑暗时代,malloc与家人一起完成整个事情,但如果我可以使用new那将是非常棒的.

我已经阅读了大量的std::vector帖子,其中每个人都说"不,你不能这样做,使用",但它们都是在2011年8月之前发布的,我希望自C +曙光以来可能有所改变的希望+11.那么告诉我,我是幸运的,还是我必须恢复到C风格的内存分配?

Meh*_*dad 8

realloc无论如何你应该完全避免,因为你不能像这样移动C++对象.

  • 使用buf = new unsigned char[sizeof(T) * capacity]创建一个新的缓冲
  • 从现在开始将分配unsigned char *到T *并使用这些T指针
  • 通过"放置new" 构建新元素,如new (&buf[i]) T(original_copy)
  • 要将缓冲区复制到更大的缓冲区,首先分配新的缓冲区,使用std::uninitialized_copy(不 std::copy),然后使用buf[i].~T()旧的缓冲区中的元素来销毁旧缓冲区中的元素delete [] buf.

所有这一切都假设您不必担心异常安全,这对于分配来说可能是可以的.
要知道,在现实世界中的代码你必须保证异常安全,这是一个很多比这更繁琐.

  • 坏!使用`static_cast <T*>(:: operator new(sizeof(T)*cap))`获取内存,如果有的话.然后使用placement new来粘贴那里的东西.这样,您可以使用普通指针算法来标记您的第一个,最后一个和最后一个.我甚至会说这对于赋值而言过于复杂,并且只会直接执行新的T [capacity]并且需要默认的可构造性. (3认同)
  • 这个想法是你明确键入了内存. (2认同)
  • Re"你不能像这样移动C++对象",好吧,虽然std :: vector一般不能使用realloc,但它确实可以像C++那样移动它.问题不在于realloc,而在于容器设计(需要简单的标准分配器).`realloc`将为*合适的容器*提供非常好的性能提升,没问题(大于`std :: vector`的实现问题,即). (2认同)

Ton*_*roy 6

问题realloc在于可能将现有数据移动到不同范围的连续地址.如果它需要这样做,假设它是一个C函数,数据被复制而没有任何对C++对象生命周期的点头:

  • 不使用复制/移动构造函数
  • 之后不会为源对象调用析构函数

这可能会导致致命的后果 - 例如,当被移动的对象包含指向空闲的内存区域中的地址的指针/引用时.

遗憾的是,正常的malloc实现不允许回调钩子允许您用自己的C++替换内存内容复制代码 - 安全实现.如果你确定你可以尝试找到一个更灵活的"malloc"库,但它不太可能值得麻烦和风险.

因此,在一般情况下,您应该使用new更改容量,复制/移动每个对象以及delete之后的原件.

如果您确定您的数据足够简单以至于a- memcpystyle重定位不会造成不良后果,那么您可以使用realloc(风险自负).