c++ - 可以使用 realloc 安全地重新分配普通可复制对象的存储吗?

标签 c++ c++11 language-lawyer realloc object-lifetime

我知道trivially copyable对象可以安全地复制我的 malloc 到适当的存储位置1 并且目标对象将具有与源相同的值。

realloc 也可以吗?也就是说,如果 realloc 一些存储包含一些 T 类型的对象,并且 realloc 决定移动和复制 block ,那么新分配的存储完好无损并开始了它们的生命周期,旧存储中对象的生命周期是否会安全结束?


1 在问这个问题时,我假设“适当的存储位置”包括适当对齐和大小的未初始化存储,但作为 M.M's answer below 认为这实际上并没有得到标准的很好支持。这会使 realloc 成为问题,因为它总是复制到未初始化的存储中。

最佳答案

realloc 不能用于安全移动对象,即使是普通可复制的类型,因为realloc 无法在未初始化的存储中创建新对象.

特别是,根据 C++14 [basic.life]/1:

The lifetime of an object of type T ends when:

  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or

  • the storage which the object occupies is reused or released.

调用 realloc 释放或重用存储(即使没有发生重新分配,我认为,尽管这对你的问题没有实际意义)。因此对象的生命周期结束。

[intro.objects]/1 涵盖了创建对象的情况:

An object is created by a definition (3.1), by a new-expression (5.3.4) or by the implementation (12.2) when needed.

这不包括realloc;所以 realloc 调用结束了旧对象的生命周期并且不创建新对象。

这不仅意味着 realloc 不适合复制平凡可复制的对象,还意味着使用 mallocoperator new(size_t) 获取未初始化的存储,后跟从现有对象到该存储的 memcpy 不会创建该对象的可用拷贝,因为目标对象也未创建 在那种情况下。


另请参阅:reinterpret_cast creating a trivially-default-constructible object , 或 constructing a trivially copyable object with memcpy进一步讨论将字节复制到新位置不会在该位置创建对象这一事实。

关于c++ - 可以使用 realloc 安全地重新分配普通可复制对象的存储吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46838729/

相关文章:

c++ - 无法更改 MFC 应用程序图标

c++ - std::get 与 std::tuple 的效率

C++0x 右值引用 - 左值-右值绑定(bind)

c++ - 如何调用 clang++ 或 g++ 来准确复制两个不同标准版本中的需求

c - '#' 字符是否必须位于 C 预处理器中一行的开头?

javascript - 将 JavaScript 数字 n 转换为字符串 s,使得 Object.is(eval(s), n) 对于所有 n?

c++ - C++中指向数组对象的指针

c++ - Vector 内的类切片

c++ - 创建新指针循环时,输出取消引用的指针不会增加内存使用量

C++ std::bind 重新绑定(bind)函数