Java の詳細についてはわかりませんが、C++ では次のようにnew
なります。new[]
メモリを割り当てる
new T
または式がある場合new T(args)
、コンパイラは、メモリを取得するために呼び出す関数を決定します。
- 型
T
に適切なメンバーがある場合、そのメンバーoperator new
が呼び出されます
それ以外の場合、ユーザーが適切なグローバルoperator new
を提供した場合、そのグローバルが呼び出されます。
要求されたメモリを割り当てることができない場合operator new
は、 で設定できる新しいハンドラ関数が呼び出されますset_new_handler
。その関数は、割り当てが成功するようにいくらかのスペースを解放するか、プログラムを終了するか、型の例外またはそれstd::bad_alloc
から派生した例外をスローする可能性があります。デフォルトの new ハンドラーは単にstd::bad_alloc
.
メモリ割り当てのために呼び出されるnew T[n]
以外の場合も同じことが起こります。operator new[]
オブジェクトを作成します。新しく割り当てられたメモリ内のオブジェクト。
オブジェクトのnew T(args)
対応するコンストラクターが呼び出されます。operator delete
コンストラクターが例外をスローした場合、対応する( と同じ場所にありますoperator new
)を呼び出すことにより、メモリの割り当てが解除されます。
POD (つまり、組み込み型または基本的に C の構造体/共用体)new T
であるかどうかによって異なります。T
T が POD の場合は何も起こらず、そうでない場合は のように扱われnew T()
ます。
かどうかにnew T[n]
も依存しT
ますPOD
。繰り返しますが、POD は初期化されません。非 POD の場合、デフォルトのコンストラクターが順番に各オブジェクトに対して呼び出されます。1 つのオブジェクトのデフォルト コンストラクターがスローした場合、それ以上のコンストラクターは呼び出されませんが、既に構築されているオブジェクト (コンストラクターがスローしたばかりのオブジェクトは含まれません) は逆の順序で破棄されます (つまり、デストラクタが呼び出されます)。次に、メモリは適切な .xml で割り当て解除されますoperator delete[]
。
新しく作成されたオブジェクトへのポインターを返します。new[]
ポインターは、割り当てられたメモリの先頭を指していない可能性が高いことに注意してください。これは、構築されたオブジェクトの前に割り当てられたオブジェクトの数に関する情報が存在する可能性があるためです。これは、破棄するオブジェクトの数delete[]
を把握するために使用されます。
delete ptr
いずれの場合も、オブジェクトは( normal で割り当てられたオブジェクトの場合new
) またはdelete[] ptr
( array で作成されたオブジェクトの場合)で破棄されるまで存続しますnew T[n]
。サード パーティのライブラリを追加しない限り、C++ にはガベージ コレクションはありません。
operator new
and をoperator delete
直接呼び出して生メモリを割り当てることもできることに注意してください。operator new[]
とについても同様ですoperator delete[]
。ただし、これらの低レベル関数の場合でも、呼び出しを混在させることはできないことに注意してください。たとえば、 で割り当てたメモリの割り当てを解除operator delete
するなどですoperator new[]
。
いわゆるplacement newを使用して、割り当てられたメモリ内のオブジェクトを(どのように取得したかに関係なく)copnstructすることもできます。これは、生メモリへのポインタを への引数として与えることによって行われnew
ますnew(pMem) T(args)
。このような明示的に構築されたオブジェクトを破棄するには、オブジェクトのデストラクタを直接呼び出すことができますp->~T()
。
operator new
配置 newは、ポインタを追加の引数として取り、それを返すだけのan を呼び出すことによって機能します。この同じメカニズムを使用して、operator new
対応する追加の引数を取るオーバーロードに他の情報を提供することもできます。ただし、対応する を定義することはできますがoperator delete
、それらは構築中にオブジェクトが例外をスローしたときのクリーンアップにのみ使用されます。「プレースメントの削除」構文はありません。
C++ によって既に提供されている配置の新しい構文のもう 1 つの使用法は、新しいものではありません。これは追加のパラメーターを取り、割り当てが失敗した場合に null ポインターを返すという点でのみ、std::nothrow
通常と異なります。new
new
また、C++ の唯一のメモリ管理メカニズムではないことに注意してください。一方では、C 関数malloc
とがありfree
ます。通常はoperator new
をoperator new[]
呼び出すだけですがmalloc
、これは保証されません。したがって、これらの形式を混在させることはできません (たとえば、 でfree
割り当てられたメモリを指すポインタを呼び出すことによってoperator new
)。一方、STL コンテナーは、オブジェクトの割り当て/割り当て解除、およびコンテナー内のオブジェクトの構築/破棄を管理するオブジェクトであるアロケーターを通じて割り当てを処理します。
そして最後に、ライフタイムが言語によって直接制御されるオブジェクト、つまり静的ライフタイムと自動ライフタイムのオブジェクトがあります。自動有効期間オブジェクトは、ローカル スコープで型の変数を定義するだけで割り当てられます。それらは、実行がその行を通過すると自動的に作成され、実行がスコープを離れると自動的に破棄されます (スコープが例外によって残されることを含みます)。静的有効期間オブジェクトは、キーワード static を使用して、グローバル/名前空間スコープまたはローカル スコープで定義されます。これらは、プログラムの起動時 (グローバル/名前空間スコープ) または定義行が実行されるとき (ローカル スコープ) に作成され、プログラムの最後まで存続し、構築の逆順で自動的に破棄されます。
一般に、自動変数または静的変数は、動的割り当て (new
つまり、アロケーターで割り当てるすべてのもの) よりも優先されます。これは、独自に行う必要がある動的割り当てとは異なり、コンパイラーが適切な破棄を処理するためです。オブジェクトを動的に割り当てた場合、同じ理由で自動/静的オブジェクト (コンテナー、スマート ポインター) によってその有効期間を管理することが望ましいです。