cプログラムメモリレイアウト



C Program Memory Layout



以前のブログで、Cプログラムデータのメモリ割り当てについて書いたことがあります。その際、コード領域、静的ストレージ領域、定数領域、ヒープ領域、スタック領域について簡単に説明しました。以前のものを確認できます。記事、Sedum、cプログラムのメモリレイアウトの詳細について話しましょう。 cプログラムの一般的なメモリレイアウトは次のとおりです。1。テキストセグメント2.初期化されたデータセグメント3.初期化されていないデータセグメント4.ヒープ5.スタック。あなたの理解を容易にするために絵を見てください:

この図から、メモリ内のcプログラムは、テキストセクション、初期化されたデータセクション、初期化されていないデータセクション、ヒープ領域、およびメモリ内の最初のアドレスから上位アドレスまでのスタック領域であることがわかります。これらのパーティションを個別に理解しましょう。1。テキストセグメント:コードセグメントまたはテキストとも呼ばれます。これは、メモリプログラムまたはオブジェクトファイルの一部です。メモリ領域として実行可能命令が含まれています。テキストセグメントは、スタックオーバーフローがそれをカバーするのを防ぐために、スタック上またはヒープの下に配置されます。通常、テキストセグメントは共有され、テキストエディタ、cコンパイラ、シェルなど、頻繁に実行されるメモリに1つのコピーのみを配置する必要があります。さらに、プログラムが誤って実行されるのを防ぐため、テキストセグメントは通常読み取り専用です。その命令を変更します。 2.初期化されたデータセグメント:データセグメントとも呼ばれるデータセグメントは、プログラムの仮想アドレスの一部であり、プログラマーによって初期化されたグローバル変数と静的変数が含まれます。データセクションは読み取り専用ではないことに注意してください。プログラムの実行中にデータが変更される可能性があるため、このセクションはさらに初期化読み取り専用領域、初期化読み取り/書き込み領域に分割できます。例えば、

Cで定義されたグローバル文字列はC [] = 'hello world'で定義され、メイン(つまりグローバル)の外側のint debug = 1などのCステートメントは、初期化された読み取り/書き込み領域に格納されます。グローバルCステートメント(const char * string = 'hello world'など)は、文字列リテラル 'hello world'を初期化された読み取り専用領域に格納し、文字ポインター変数stringは初期化された読み取り/書き込み領域にあります。

例:static int i = 10はデータセグメントに格納され、global int i = 10もデータセグメントに格納されます



3.初期化されていないデータセグメント:

通常「bss」セクションと呼ばれる初期化されていないデータセクションは、「シンボルで始まるブロック」を表す古代のアセンブラ演算子にちなんで名付けられています。このセクションのデータは、プログラムが開始する前に、カーネルによって算術0に初期化されます。

初期化されていないデータは、データセグメントの最後から始まり、ゼロに初期化されているか、ソースコードで明示的に初期化されていないすべてのグローバル変数と静的変数が含まれています。



たとえば、変数はstatic intiとして宣言されますBSSセクションに含まれます。
たとえば、グローバル変数はintjとして宣言されますBSSセクションに含まれます。

4.スタック:

スタック領域は伝統的にスタック領域に隣接しており、成長方向は反対です。スタックポインタがヒープポインタに遭遇すると、使用可能なメモリが使い果たされます。(最新の大規模なアドレス空間と仮想メモリテクノロジを使用すると、ほとんどどこにでも配置できますが、通常は反対方向に配置されます)。



スタック領域には、通常はメモリの上位部分にあるプログラムスタックであるLIFO構造が含まれています。標準のPCx86コンピュータアーキテクチャでは、アドレスがゼロに増加します他のいくつかのアーキテクチャでは、その成長は反対方向です。「スタックポインタ」レジスタは、スタックの最上位を追跡します値がスタックに「プッシュ」されるたびに調整が行われます。関数呼び出しの値のセットをプッシュすることは「スタックフレーム」と呼ばれますスタックフレームには、少なくともリターンアドレスが含まれています。

関数が呼び出されるたびに保存される自動変数と情報を格納するスタック。関数が呼び出されるたびに、返されたアドレスと呼び出し元の環境に関する情報(一部のマシンレジスタなど)がスタックに保存されます。次に、新しく呼び出された関数は、スタック内の自動変数と一時変数にスペースを割り当てます。これは、Cの再帰関数がどのように機能するかです。再帰関数がそれ自体を呼び出すたびに、新しいスタックフレームが使用されるため、変数のセットが別の関数インスタンスの変数に干渉することはありません。

5.ヒープ:

ヒープは、動的メモリ割り当てが通常発生する部分です。

ヒープ領域はBSSセグメントの終わりから始まり、そこからより大きなアドレスに拡大します。ヒープ領域はmalloc、realloc、およびfreeによって管理され、そのサイズはbrkおよびsbrkシステムコールを使用して調整できます(brk / sbrkおよび単一の「ヒープ領域」を使用する場合、malloc / realloc /を満たす必要はないことに注意してください。彼らが達成できる無料の契約mmapを使用して、仮想メモリの潜在的な非連続領域がプロセスの仮想アドレス空間に予約されます。ヒープ領域は、プロセス内のすべての共有ライブラリと動的にロードされるモジュールによって共有されます。