简体   繁体   中英

placement new VS explicit constructor call in C++

recently I have come across these two ways of creating an object in a specific place in memory:
1.

void* mem = malloc(sizeof(T));
T* obj = new(mem) T();


2.

T* obj = (T*)malloc(sizeof(T));
*obj = T();

The second way is a bit shorter...are there other differences? Regards Mateusz

The second way is wrong, the first is right.

You're invoking the assignment operator on a T instance containg garbage data. The assignment operator expects the instance to have been initialized correctly - It could eg delete member variables before assigning, which would cause all sorts of funny crashes. See eg:

struct Foo {
  std::string * Data;
  Foo() : Data(0) {}
  Foo(Foo const & R)  { Data = new std::string(*R.Data); }
  ~Foo() { delete Data; }
  Foo & operator=(Foo const & R) {
    delete Data;
    Data = new std::string(*R.Data);
    return *this;
  }

};

The first way will ensure Foo::Foo() is called - thus properly initializing Data . The second way will lead to a delete Data; where Data points to some random location in memory.

EDIT:

You can test this the following way:

void* mem = malloc(sizeof(Foo));
memset(mem, 0xCC, sizeof(Foo)); // malloc doesn't guarantee 0-init
Foo* obj = new(mem) Foo();

And:

Foo * obj = (Foo*)malloc(sizeof(Foo));
memset(obj, 0xCC, sizeof(Foo)); // malloc doesn't guarantee 0-init
*obj = Foo(); // Crash
*obj = T();

This statement constructs a T object on the stack, and then does an assignment to *obj . It's wrought with unintended consequences.

On the other hand,

T* obj = new (mem) T();

This statement initializes a designated memory buffer, mem , by executing T() constructor method, as intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM