在C++中放置新的VS显式构造函数调用

Mat*_*usz 3 c++ explicit-constructor placement-new

最近我遇到了这两种在内存中特定位置创建对象的方法:
1.

void* mem = malloc(sizeof(T));
T* obj = new(mem) T();
Run Code Online (Sandbox Code Playgroud)


2.

T* obj = (T*)malloc(sizeof(T));
*obj = T();
Run Code Online (Sandbox Code Playgroud)

第二种方式有点短......还有其他差异吗?关心马特乌斯

Eri*_*rik 7

第二种方式是错误的,第一种方式是对的.

您正在调用包含垃圾数据的T实例上的赋值运算符.赋值运算符期望实例已经正确初始化 - 它可以例如在分配之前删除成员变量,这将导致各种有趣的崩溃.见例如:

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;
  }

};
Run Code Online (Sandbox Code Playgroud)

第一种方式将确保Foo::Foo()被调用 - 从而正确初始化Data.第二种方法将导致delete Data;这里Data指向内存的任意位置.

编辑:

您可以通过以下方式测试:

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

和:

Foo * obj = (Foo*)malloc(sizeof(Foo));
memset(obj, 0xCC, sizeof(Foo)); // malloc doesn't guarantee 0-init
*obj = Foo(); // Crash
Run Code Online (Sandbox Code Playgroud)