Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is previously initialize memory guaranteed to persist after a placement 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 second assert guaranteed to hold, even though aSecond is not value-initialized? Logically, it should, because the memory isn't overwritten, but is it specified by the standard?

like image 715
Luchian Grigore Avatar asked Jul 30 '12 21:07

Luchian Grigore


1 Answers

No.

When you construct the second object on 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 non-trivial destructor (§12.4), the destructor call starts, or
  • the storage which the object occupies is reused or released.

When the second object is created, since A has the implicit default constructor, the x member is default-initialized, and thus no initialization is performed (§8.5/6):

To default-initialize an object of type T means:

  • [...]

  • otherwise, no initialization is performed.

And this means the object has indeterminate value (§5.3.4/15):

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

  • If the new-initializer is omitted, the object is default-initialized (§8.5); if no initialization is performed, the object has indeterminate value.

And in case you think that the value is not indeterminate because you previously initialized another object on that storage location: the standard discards that possibility as well by saying the properties of the previous object no longer apply once its lifetime ends (§3.8/3):

The properties ascribed to objects throughout this International Standard apply for a given object only during its lifetime.

like image 143
R. Martinho Fernandes Avatar answered Sep 20 '22 00:09

R. Martinho Fernandes