是以前初始化的内存,保证在放置新调用后保持不变

Is previously initialize memory guaranteed to persist after a placement new call?

本文关键字:新调用 调用 初始化 内存      更新时间:2023-10-16

假设我有以下内容:

struct A
{
   int x;
};
//...
A* aOriginal = new A();  //value construct aOriginal
assert( aOriginal->x == 0 );
A* aSecond = new (aOriginal) A;
assert( aSecond->x == 0 );

即使aSecond未初始化值,第二个断言是否保证保持?从逻辑上讲,它应该这样做,因为内存没有被覆盖,但它是由标准指定的吗?

否。

当您在同一存储位置上构建第二个对象时,前一个对象的寿命结束(§3.8/1):

[…]类型为T的对象的生存期在以下情况下结束:

  • 如果T是具有非平凡析构函数的类类型(§12.4),则析构函数调用开始,或者
  • 对象占用的存储器被重新使用或释放

创建第二个对象时,由于A具有隐式默认构造函数,x成员默认初始化,因此不执行初始化(§8.5/6):

默认初始化类型为T的对象意味着:

  • […]

  • 否则,不执行初始化。

这意味着对象具有不确定值(§5.3.4/15):

创建T类型对象的新表达式将该对象初始化如下:

  • 如果省略了新初始化器,则对象为默认初始化的(§8.5);如果没有执行初始化,该对象的值不确定

如果您认为该值不是不确定的,因为您之前初始化了该存储位置上的另一个对象:标准也放弃了这种可能性,即前一个对象的属性在其寿命结束后不再适用(§3.8/3):

本国际标准中赋予物体的特性仅适用于给定物体的使用寿命。