最近、メモリ内の特定の場所にオブジェクトを作成する2つの方法に出くわしました:
1。
void* mem = malloc(sizeof(T));
T* obj = new(mem) T();
2.2。
T* obj = (T*)malloc(sizeof(T));
*obj = T();
2番目の方法は少し短いです...他に違いはありますか?よろしくマテウス
最近、メモリ内の特定の場所にオブジェクトを作成する2つの方法に出くわしました:
1。
void* mem = malloc(sizeof(T));
T* obj = new(mem) T();
2.2。
T* obj = (T*)malloc(sizeof(T));
*obj = T();
2番目の方法は少し短いです...他に違いはありますか?よろしくマテウス
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
*obj = T();
T
このステートメントは、スタック上にオブジェクトを構築し、 への代入を行い*obj
ます。それは意図しない結果をもたらします。
一方で、
T* obj = new (mem) T();
このステートメントは、意図したとおり、コンストラクター メソッドmem
を実行することによって、指定されたメモリ バッファー を初期化します。T()