CとC++プログラムのメモリ割り当てメカニズム

2951 ワード

プログラムのメモリ割当て
一:C言語におけるメモリメカニズム
C言語では、メモリは主に以下の5つのストレージ領域に分けられます.
(1)スタック(Stack):関数内に位置する局所変数(関数実パラメータを含む)は、コンパイラが割り当て解放を担当し、関数が終了し、スタック変数が失効する.
(2)スタック(Heap):プログラマがmalloc/calloc/reallocで割り当て,freeが解放する.プログラマがfreeを忘れた場合、メモリが漏洩し、プログラム終了時にOSでメモリが回収されます.
(3)グローバル領域/静的領域(Global Static Area):グローバル変数と静的変数格納領域であり、プログラムがコンパイルされると、その領域が存在する.また、C言語で初期化されたグローバル変数と静的変数と、初期化されていないものは隣接する2つの領域に配置されている(C++では、グローバル変数と静的変数コンパイラがこれらの変数に自動的に初期化して付与するため、区別されていない).グローバル変数はメモリ領域を占有し、メンテナンスが容易ではないため、使用しないことをお勧めします.プログラム終了時にリリースします.
(4)Cスタイル文字列定数記憶領域:文字列定数を専用に格納する場所であり,プログラム終了時に解放される.
(5)プログラムコード領域:プログラムバイナリコードを格納する領域.


スタックとスタックの違い
  • 申請方式
  • stack:システムによって自動的に割り当てられます.例えば、関数内の局所変数int bを宣言する.システムはスタックの中でbのために空間
  • を自動的に開く.
  • heap:プログラマーが自分で申請し、サイズを指定する必要があります.cではp 1=(char)malloc(10)などのmalloc関数を使用します.C++では、p 2=(char)new(10)などのnew演算子を使用します.ただし、p 1、p 2自体はスタック内にあることに注意してください.
  • 出願後のシステムの応答
  • スタック:スタックの残りのスペースが申請されたスペースより大きい場合、システムはプログラムにメモリを提供します.そうしないと、例外プロンプトスタックがオーバーフローします.
  • スタック:まず、オペレーティングシステムに空きメモリアドレスを記録するチェーンテーブルがあることを知っておく必要があります.システムがプログラムの申請を受け取ると、チェーンテーブルを遍歴し、申請空間よりも大きな最初の空間のスタックポイントを探し、その後、そのノードを空きノードチェーンテーブルから削除し、そのノードの空間をプログラムに割り当てます.また、多くのシステムでは、このメモリ領域の最初のアドレスに今回の割り当てのサイズが記録され、コードのdelete文がこのメモリ領域を正しく解放することができます.また,見つかったスタックポイントの大きさが申請の大きさに等しいとは限らないため,余分な部分を自動的に空きチェーンテーブルに再配置する.
  • 申請サイズの制限
  • スタック:Windowsでは、スタックは低アドレスに拡張されたデータ構造であり、連続したメモリの領域である.スタックトップのアドレスとスタックの最大容量はシステムで予め定められており、WINDOWSではスタックの大きさは2 M(1 Mということもあり、つまり1つのコンパイル時に決定される定数)であり、申請された空間がスタックの残りの空間を超えるとoverflowが提示される.したがって、スタックから得られる空間は小さい.
  • スタック:スタックは高アドレスに拡張されたデータ構造であり、不連続なメモリ領域である.これは,システムがチェーンテーブルで格納する空きメモリアドレスであるため,当然不連続であり,チェーンテーブルの遍歴方向は低アドレスから高アドレスである.スタックのサイズは、コンピュータシステムで有効な仮想メモリに制限されます.このことから,スタックが得られる空間は比較的柔軟であり,比較的大きいことが分かる.
  • 出願効率の比較:
  • スタック:システムによって自動的に割り当てられ、速度が速い.しかし、プログラマーはコントロールできません.
  • スタック:newによって割り当てられたメモリで、一般的に速度が遅く、メモリの破片が発生しやすいが、最も便利である.
  • また、WINDOWSでは、Virtual Allocでメモリを割り当てるのが一番です.彼はスタックではなく、スタックではなく、プロセスのアドレス空間に直接メモリを残しています.最も使いにくいですが.しかし、スピードが速く、最も柔軟です.
  • スタックおよびスタック内の記憶コンテンツ
  • スタック:関数呼び出し時に、最初にスタックに入ったのは主関数の次の命令(関数呼び出し文の次の実行可能文)のアドレスで、それから関数の各パラメータで、大多数のCコンパイラの中で、パラメータは右から左へスタックに入って、しかし後は関数の中の局所変数です.静的変数はスタックに入らないことに注意してください.今回の関数呼び出しが終了すると、ローカル変数は先にスタックを出て、それからパラメータで、最後にスタックトップポインタは最も最初に保存されたアドレス、つまりメイン関数の次の命令を指し、プログラムはこの点から実行を継続します.
  • スタック:通常、スタックのヘッダにスタックのサイズを1バイトで格納します.スタックの具体的な内容はプログラマーが手配します.
  • フラグメントの問題スタックにとって、頻繁なnew/deleteなどの操作はメモリ空間の不連続をもたらし、それによって大量のフラグメントをもたらし、プログラムの効率を低下させる.スタックの場合、スタックは後進先出(LIFO)のキューであるため、この問題は発生しません.
  • 成長正方晶スタックの成長方向は上向き、すなわちこのメモリアドレスに増加する方向である.スタックの場合、成長方向は下向きであり、メモリアドレスが減少する方向に成長します.
  • 小結堆と桟の違いは以下の比喩で見ることができる:桟を使うのは私たちがレストランで食事をするのと同じで、料理を注文する(申請を出す)、お金を払う、食べる(使用する)だけで、満腹になったら行って、野菜を切る、野菜を洗うなどの準備と茶碗を洗う、鍋を洗うなどの掃除の仕事を気にする必要はありません.彼のメリットは速いですが、自由度は小さいです.山を使うのは自分で好きな料理を作るようなもので、面倒ですが、自分の好みに合っていて、自由度が高いです.