メモリ管理 : フレーム割り当て
フレームへの割り当てという言い方は、関数が呼び出されるたびにセットアップされる "スタック フレーム" にちなんでいます。 スタック フレームは、関数のローカルに定義された変数や関数への引数を一時的に保持するメモリ領域です。 フレーム変数は、そのための領域がコンパイラによって自動的に割り当てられることから、"自動" 変数とも呼ばれます。
フレーム割り当てには、2 つの大きな特徴があります。 まず、ローカル変数を定義すると、変数全体を保持するために必要な領域がスタック フレームに割り当てられます。たとえそれが大きな配列やデータ構造であっても同様です。 次に、フレーム変数は、スコープから抜けたときに自動的に削除されます。
void MyFunction()
{
// Local object created on the stack
CString strName;
// Object goes out of scope and is deleted as function ends
}
関数のローカル変数では、このスコープの遷移は関数が終了したときに起こりますが、中かっこが入れ子構造になっている場合、フレーム変数のスコープが関数よりも小さくなる場合があります。 このようにフレーム変数が自動的に削除されるという点は非常に重要です。 単純なプリミティブ型 (int
、byte など) や配列、データ構造の場合、自動削除では単に、変数によって使用されていたメモリが回収されます。 変数はスコープから抜けているので、どのような方法でもアクセスすることはできません。 一方、C++ オブジェクトの場合、自動削除のプロセスはもう少し複雑です。
オブジェクトがフレーム変数として定義されている場合、定義が検出された時点で、対応するコンストラクターが自動的に呼び出されます。 オブジェクトがスコープから抜けると、対応するデストラクターが自動的に呼び出され、その後、そのオブジェクトのメモリが回収されます。 このように構築と破棄が自動的に行われるしくみはきわめて有益ですが、自動呼び出し、とりわけデストラクターの呼び出しには注意が必要です。
オブジェクトをフレームに割り当てる主な利点は、それらが自動的に削除されることです。 フレームにオブジェクトを割り当てれば、オブジェクトを破棄し忘れることによって生じるメモリ リークを開発者が心配する必要はありません。 (メモリ リークの詳細については、次の記事 を参照してください。MFC でのメモリ リークの検出。)フレーム割り当ての欠点は、フレーム変数をスコープ外で使用できないことです。 フレーム割り当てとヒープ割り当ての選択でもう 1 つ考慮すべき点は、大きな構造体やオブジェクトの格納には通常、スタックではなくヒープを使用した方がよいということです。スタック領域は限られていることが多いためです。