3

最近、メモリ内の特定の場所にオブジェクトを作成する2つの方法に出くわしました:
1。

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


2.2。

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

2番目の方法は少し短いです...他に違いはありますか?よろしくマテウス

4

2 に答える 2

7

2 番目の方法は間違っていますが、最初の方法は正しいです。

ガベージ データを含む 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;
  }

};

最初の方法は確実Foo::Foo()に呼び出されます - したがって、適切に初期化されますData。2 番目の方法は、メモリ内のランダムな場所を指すdelete Data;whereにつながります。Data

編集:

これは次の方法でテストできます。

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

と:

Foo * obj = (Foo*)malloc(sizeof(Foo));
memset(obj, 0xCC, sizeof(Foo)); // malloc doesn't guarantee 0-init
*obj = Foo(); // Crash
于 2011-03-11T22:29:58.100 に答える
1
*obj = T();

Tこのステートメントは、スタック上にオブジェクトを構築し、 への代入を行い*objます。それは意図しない結果をもたらします。

一方で、

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

このステートメントは、意図したとおり、コンストラクター メソッドmemを実行することによって、指定されたメモリ バッファー を初期化します。T()

于 2011-03-11T22:30:31.007 に答える