可能性のある複製:
スタックとヒープはどこにありますか
私はC++でプログラミングしており、スタックメモリとヒープメモリの正確な違いを常に疑問に思っています。私が知っているのは、newを呼び出すと、ヒープからメモリを取得することだけです。ローカル変数を作成する場合、スタックからメモリを取得します。インターネットに関するいくつかの調査の後、最も一般的な答えは、スタックメモリは一時的であり、ヒープメモリは永続的であるということです。
スタックおよびヒープメモリモデルは、オペレーティングシステムまたはコンピューターアーキテクチャの概念ですか?それで、その一部はスタックとヒープメモリモデルに従わないかもしれませんし、それらのすべてはそれに従いますか?
スタックメモリとヒープメモリは、仮想メモリのメモリモデル(ディスクとRAMの間でメモリをスワップする可能性があります)を抽象化したものです。スタックメモリとヒープメモリの両方が物理的にRAMまたはディスクの可能性がありますか?それでは、ヒープの割り当てが対応するスタックよりも遅いと思われる理由は何ですか?
また、メインプログラムはスタックまたはヒープで実行されますか?
また、プロセスが割り当てられたスタックメモリまたはヒープメモリを使い果たすとどうなりますか?
ありがとう
C++では、スタック変数はローカル変数が保存/構築される場所です。スタックは、関数に渡されるパラメーターを保持するためにも使用されます。
スタックはstd :: stackクラスに非常に似ており、パラメータをプッシュしてから関数を呼び出します。関数は、スタックの最後にあると予想されるパラメーターを認識します。同様に、関数はローカルからスタックにプッシュし、関数から戻る前にスタックからポップすることができます。 (注意-コンパイラの最適化と呼び出し規約はすべて、物事がこれほど単純ではないことを意味します)
スタックは本当に低レベルから最もよく理解されており、このリンクをお勧めします アセンブリーの手法-スタックのパラメーターの受け渡し 。まれに、C++からの手動スタック操作を検討することはほとんどありません。
通常、スタックはCPUキャッシュ内にあるため、スタックが優先されるため、スタックに格納されているオブジェクトを含む操作は高速になる傾向があります。ただし、スタックは限られたリソースであり、大きなものには使用しないでください。スタックメモリが不足することを スタックバッファオーバーフロー と呼びます。遭遇するのは重大なことですが、クレイジーな再帰関数またはそれに類するものがない限り、実際に遭遇するべきではありません。
ヒープメモリは、rskarの言うとおりです。一般的に言えば、新規割り当てられたC++オブジェクト、またはmallocのようなもので割り当てられたメモリブロックは、ヒープ上に配置されます。ほとんどの場合、ヒープメモリは手動で解放する必要がありますが、スマートポインタクラスなどを実際に使用して、忘れずに解放する必要があります。ヒープメモリが不足すると、std :: bad_allocが発生する可能性がありますか?.
スタックメモリは、特にCPUのスタックレジスタを介してアクセス可能なメモリの範囲です。スタックは、アセンブリ言語で「ジャンプサブルーチン」-「リターン」コードパターンを実装する方法として、またハードウェアレベルの割り込み処理を実装する手段として使用されました。たとえば、割り込み中に、スタックを使用して、ステータス(操作の結果を示す)およびプログラムカウンター(割り込みが発生したときのプログラム内のCPU)を含むさまざまなCPUレジスタを格納しました。
スタックメモリは、通常のCPU設計の結果です。厳密に後入れ先出し設計であるため、割り当て/割り当て解除の速度は高速です。スタックレジスタの移動操作とデクリメント/インクリメント操作の簡単な問題です。
ヒープメモリは、プログラムがロードされ、スタックメモリが割り当てられた後に残ったメモリです。グローバル変数スペースを含む場合と含まない場合があります(慣習の問題です)。
仮想メモリとメモリマップデバイスを備えた最新のプリエンプティブマルチタスクOSは、実際の状況をより複雑にしますが、それは簡単に言えばスタックとヒープです。
これは言語の抽象化です-一部の言語には両方があり、一部はどちらか、どちらもありません。
C++の場合、コードはスタックでもヒープでも実行されません。 new
を呼び出して解放することなく、delete
を繰り返し呼び出してループ内のメモリを割り当てることにより、ヒープメモリが不足した場合の動作をテストできます。 ただし、これを行う前にシステムのバックアップを作成します。