2012-02-25 4 views
3

が、私は最近、C++クラスを再初期化するために、new演算子の珍しい使用に走った、コードは次のとおりです。このコードが実行されるC++ 'new'演算子 - 使用モード?

#include <iostream> 
struct Test { Test() { std::cout<<"Test Ctor\n"; } }; 
int main() 
{ 
    Test t ; 
    new (&t) Test; 
    return 0 ; 
} 

場合は、テストctorのは二回と呼ばれています。この場合、 'new'演算子は新しいメモリを割り当てるのではなく、メモリのソースとしてオブジェクトへのポインタを使用しているように見え、valgrindはメモリリークを確認しません。

誰かがこの「新しい」演算子の使用についていくつか光を当てることができますか?

+4

それは['配置new']と呼ばれています(http://stackoverflow.com/questions/222557/cs-placement-new) –

答えて

4

この演算子は、プレースメントnewと呼ばれます。メモリ割り当てを行わずに、指定されたアドレスでオブジェクトのコンストラクタを実行します。これは、大きな配列を最初に割り当て、次にそれに多くのオブジェクトを構築するときなどに使用できます。

+0

これは実際に遍在的に使用されています動的なコンテナ内の標準ライブラリ全体(アロケータを介して) –

+2

これは、標準ライブラリの使用とは異なり、有効な使用ではありません。これは既存のライブオブジェクト上に構築しています。 – smparkes

+1

@smparkes:Meh、 'Test'がPODの場合、これは実際にはOKです... –

3

「プレースメント・ニュー」と呼ばれ、通常、mallocが返すデフォルトではなく、特定のメモリ位置にオブジェクトを構築するために使用されます。

このように使用することは想定されていません(二重構築)。標準では、このように使用する動作がどのようになるかは言いません。

これは少なくとも過去には言われました。グローバルなiostreamsはこの二重構造に依存していました。 (しかし、まだそれは良いアイデアにはなりません)

+0

オブジェクトを再構築するのは難しいビジネスですが、 'Test'クラスは決して破壊的であるため、このケースではおそらく定義された動作だと思います。私は間違っているかもしれません、そして、私が正しい場合でも、私はそれを助言しません。 –

+0

@SteveJessopもしこれが普通にalloc'dされた生のメモリだったら、大丈夫だと言って離れてしまうかもしれません。しかし、私が思うにコンパイラが割り当て/初期化したオブジェクトの上で実行することは、未定義です。 – smparkes

+0

@SteveJessop未割り当てのメモリであっても、それは問題ではないと思われます。それは確かにコンストラクタとデストラクタのバランスをとることに違反します。 – smparkes