2013-07-14 3 views
7

プレースメントnewを使用して作成された変数でdeleteを呼び出して、そのメモリブロックにアクセスすると、定義されていない動作が発生することは承知しています。プレースメントの削除新しい

int* x = new int[2]; 
char* ch = new(x) char(); 
*ch = 't'; 
delete ch; 

しかし、その代わりに、ヒープのメモリのブロックは、スタック上に割り当てられているし、我々はその変数に削除してからメモリにアクセス呼び出す場合、私はブロックタイプが無効であることの例外を取得します。

int x[2]; 
char* ch = new(x) char(); 
*ch = 't'; 
delete ch; 

だから質問のリストは以下のとおりです。

  • がスタックに削除を呼び出すことにより、例外ですか?
  • スタック上のメモリブロックに新しい配置を使用しても問題ありませんか?
  • はいの場合、文字ポインタを削除するにはどうすればよいですか?
  • メモリの1つのブロックに複数の変数を割り当てることは可能ですか?
+1

http://www.parashift.com/c++-faq/placement-new.html – Drax

答えて

16

スタック上での削除の呼び出しの例外はありますか?

はい。少し明確にするために、これはC++の例外ではありません。実行時に検出されるエラーです。ランタイムがそれほどスマートでない場合は、未定義の動作にも対応できます。

スタック上のメモリブロックに新しい配置を使用しても問題ありませんか?

はい。また、alloca()Variable-length arrays(VLA)を見てみることもできます。これらはスタックにメモリを割り当てる別の2つのメカニズムです。 VLAはC99の一部であり、C++ 11(およびそれ以前)の標準ではありませんが、大部分のプロダクショングレードのコンパイラでは拡張機能としてサポートされています(C++ 14で表示される可能性があります)。

「はい」の場合、文字ポインタを削除する方法はありますか。

すべきではありません。新しいプレースメントを使用するときは、deleteを呼び出さず、単にデストラクタを呼び出します。指定されたオブジェクトoTの場合、delete o;の代わりにo->~T();に電話する必要があります。ただし、deleteまたはdelete []というコードを処理する必要がある場合は、演算子deleteとをオーバーロードし、演算子を何もしないでください(デストラクタはその時点で既に実行されています)。

プレースメントnewを使用して、1つのメモリブロックに複数の変数を割り当てることはできますか?

はい。しかし、あなたはalignment requirementsを満たすために特別な注意を払う必要があります。

+0

素晴らしい答えです。ただ1つの明確化。スタック上に新しい配置を使用している間は、割り当てられたメモリが最初から開始してから前に移動するか、ランダムに割り当てられたブロックにメモリが割り当てられます。最初のオプションが正しいと思われる。私が間違っている場合私を修正してください – Saksham

+0

@Saksham:プレースメントnewは全くメモリを割り当てていません。引数として指定されたメモリを使用します。メモリがスタックにどのように割り当てられているかは、アーキテクチャに依存しますが、それは内向きまたは外向きに拡大する可能性があります。しかし、スタック上のオブジェクトはどれもベースアドレスが低くなります。したがって、 'placement new []'で複数のオブジェクトを配置する場合は、一度にそれらのメモリを割り当てます。 –

+0

「割り当てられたメモリ」の言語が間違っています。 – Saksham

関連する問題