メモリ領域の勉強をしましょう。
プログラムを作るとメモリに格納されます。
○○セッションとかセグメントと言います。
主に以下の5つあります。
- text もしくは code
- data
- bss
- heap
- stack
メモリアドレスと対応して、
このように配置されています。

以下に順を追って説明します。
メモリセグメントとは
最初に概要を説明して、
後で実際にコードを動かして確認してみましょう。
テキストセグメント
コードセグメントとも言います。
低位(0x00000000)アドレスに最も近い領域で、
オブジェクトファイルが保存される。
コード(命令)のみが格納されるだけで、
変数などのデータの実態は、
以降の領域に配置される。
データセグメント
static修飾された変数もしくは、
グローバル変数のなかで、
(0以外で)初期化済みの変数が配置される。
bssセグメント
block started by symbolの略。
データセグメントとややこしいが、
static修飾された変数もしくは、
グローバル変数のなかで、
初期化されてない変数が配置される。
また仮に初期化されていても、
0で初期化されている場合は、bssに配置される。
初期化されてない変数の集まり領域なので、
プログラムローダによって、
実行時に0がセットされる。
ヒープセグメント
動的確保するときに使用される領域。
そのためメモリ上のヒープ領域は可変である。
例えば、ポインタで宣言して、
malloc関数を呼び出し際に、
指定したサイズはこの領域に確保される。
領域の確保は常に、
高位アドレスに向かって行われる。
要はプログラマが自由に
直接制御できる領域と言える。
スタックセグメント
初期化済みか否かを問わず、
ローカル変数が配置される。
ただしローカル変数をstatic修飾すれば、
データ or bssセグメントに
格納されることになる。
ヒープ領域同様に可変である。
プッシュ&ポップで常に、
低位アドレスに向かって、
確保されることになる。
以上が要点だけを抜き取った説明です。
イメージを掴みやすくするために、
実際にコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include<stdio.h> #include<stdlib.h> int global_var; //bss int global_var2=100; //data int main(void){ static int local; //bss static int local2=100; //data int i; //stack char *c; c = (char*)malloc(100); //heap return 0; } |
ちなみにchar *cの宣言時点ではまだ、
メモリ上のアドレスはnull (nil)で、
実態が無い状態です。
実際に確認してみる
ここではbssとdataだけどう変わるのか
簡単に見てみましょう!
まずは上のコードをコンパイルするのですが、
その際に以下のようにオプションを指定します。
3つの場合を見てみます。

dataとbssの項目を見てください。
私の環境ではint型は4バイトで,
global_var2とlocal2がdataに配置されます。
合計で8バイトになっています(①)。
一方でglobal_varとlocal変数はbssに配置され、
合計で8バイトを占領していることが分かります(①)。
ここでdataセグメントが0バイトになることを確認するために、
global_var2とlocal2をともにコメントアウトします。
すると0バイトになっています(②)。
最後に初期化されている場合でも0で初期化されていると、
それはdataではなくbssに配置される、
ということを前述しました。確認してみましょう。
global_var2 = 0に値を変更します。
すると期待通りの結果になりましたね。
dataが8から4バイトに減り、
その分だけbssが増えています!(③)
最後まで読んでいただきありがとうございました。