Is memory initialization previously guaranteed to persist after placing a new call?

Say I have the following:

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

Is the guaranteed second statement guaranteed, although aSecond not value-initialized? Logically, this should, because the memory is not overwritten, but is it specified by the standard?

+7
source share
1 answer

Not.

When you build a second object in the same storage location, the lifetime of the previous one ends (ยง3.8 / 1):

[...] The lifetime of an object of type T ends when:

  • if T is a class type with a nontrivial destructor (ยง12.4), the call to the destructor begins, or
  • The storage that the object is occupying, reusing, or freed.

When the second object is created, since A has an implicit default constructor, the x member is initialized by default and, therefore, initialization fails (ยง8.5 / 6):

To initialize an object of type T by default:

  • [...]

  • otherwise, initialization fails.

And this means that the object has an indefinite value (ยง5.3.4 / 15):

A new expression that creates an object of type T initializes this object as follows:

  • If the new initializer is omitted, the object is initialized by default (ยง8.5); if initialization fails, the object has an undefined value.

And if you think that the value is not undefined because you previously initialized another object in this repository: the standard discards this possibility, saying also that the properties of the previous object no longer apply after the end of its lifespan (ยง3.8 / 3):

Properties attributed to objects within the framework of this international standard apply to this object only during its lifetime.

+9
source

All Articles