スタックに割り当てられた変数は自動変数であるため、スタックはヒープよりも優先される必要があります。プログラムがコンテキストから外れると、それらの破棄は自動的に行われます。
実際、スタックとヒープで作成されたオブジェクトの寿命は異なります。
- 関数またはコードブロック
{}
(newによって割り当てられていない)のローカル変数は、スタック上にあります。関数から戻ると、それらは自動的に破棄されます。(それらのデストラクタが呼び出され、それらのメモリが解放されます)。
- ただし、関数の外部で使用するオブジェクトが必要な場合は、ヒープに(newを使用して)割り当てるか、コピーを返す必要があります。
例:
void myFun()
{
A onStack; // On the stack
A* onHeap = new A(); // On the heap
// Do things...
} // End of the function onStack is destroyed, but the &onHeap is still alive
この例でonHeap
は、関数の終了時にメモリが割り当てられたままになります。そのため、onHeap
どこかにポインタがないと、それを削除してメモリを解放することはできません。プログラムが終了するまでメモリが失われるため、メモリリークです。
onStack
ただし、関数を終了するときに破棄されたため、にポインタを返す場合、onStack
ポインタを使用すると未定義の動作が発生する可能性があります。使用中onHeap
はまだ完全に有効です。
スタック変数がどのように機能しているかをよりよく理解するには、ウィキペディアのこの記事など、呼び出しスタックに関する情報を検索する必要があります。関数で使用するために変数をスタックする方法について説明します。