我知道可以安全地将trivially copyable个对象复制到我的malloc
到适当的存储位置 1 ,并且目标对象将具有与源相同的值。
realloc
也可以吗?也就是说,如果realloc
某些存储包含某些类型为T
的对象,而realloc
决定移动并复制该块,则新分配的存储中的对象是否完整并已启动生命周期,旧存储中对象的生命周期是否会安全地结束?
1 在问这个问题时,我曾假设“适当的存储位置”包括合适的对齐和大小的未初始化存储,但正如下面的M.M's answer认为这实际上不是很好标准支持。这会使realloc
有问题,因为它总是复制到未初始化的存储中。
答案 0 :(得分:9)
否,realloc
不能用于安全地移动对象,即使是简单的可复制类型,因为realloc
无法在未初始化的存储中创建新对象。
特别是根据C ++ 14 [basic.life] / 1:
类型T的对象的生命周期在以下时间结束:
如果T是具有非平凡析构函数(12.4)的类类型,则析构函数调用开始,或
重复使用或释放对象占用的存储空间。
调用realloc
版本或重新使用存储(即使没有重新分配,我也会争辩,尽管这对你的问题没有意义)。所以对象的生命周期结束。
创建对象的情况由[intro.objects] / 1:
涵盖对象由定义(3.1),new-expression(5.3.4)创建 或者在需要时通过实施(12.2)。
这不包括realloc
;所以realloc调用结束了旧对象的生命周期,并且不会创建新对象。
这不仅意味着realloc
不适合复制普通的可复制对象,还意味着使用malloc
或operator new(size_t)
来获取未初始化的存储,然后是{{ 1}}从现有对象到该存储不会创建对象的可用副本,因为在这种情况下目标对象也未被创建。
另请参阅:reinterpret_cast creating a trivially-default-constructible object或constructing a trivially copyable object with memcpy,以进一步讨论将字节复制到新位置不会在该位置创建对象这一事实。
答案 1 :(得分:-3)
3.8对象生存期很明确:
T类对象的生命周期始于:
1.1获得具有适当对齐和T型尺寸的存储,并且
1.2如果对象具有非空的初始化,则其初始化完成。
与生命的终结相同。你可以忽略std其他部分的垃圾,比如[intro]!