Search on the blog

2011年9月18日日曜日

C言語の4つのメモリー領域

ちょっと気になることがあったので勉強しなおした。プロコンやってる人はヒープか、スタックなのかはよく気にすると思います。ヒープはメモリ領域が広く、スタックはメモリ領域が狭いからです。スタックのメモリオーバーしてクラッシュするとかよくあります。

 例えば、1000*1000のint[]配列をmain()関数内で宣言すると、プログラム実行時にクラッシュします。そこで、この1000*1000の配列を外部変数にしてあげます。すると、プログラムはクラッシュしません。

これは、メモリ領域が広いヒープに格納されているからだと思っていましたが、グローバル変数が格納される場所は”静的領域”と呼ばれるそうです。

ということで、勉強したことを書きます。

まず、Cには4つの記憶領域があります。
  • プログラム領域
  • 静的領域
  • ヒープ
  • スタック
 プログラム領域は、プログラム(マシン語)が格納される場所です。「なんじゃそりゃ?」と思われる方もいるかと思いますが、ノイマン型コンピュータでは、プログラム内蔵方式でプログラムが実行されます。つまり、命令自体もメモリに格納されていて、プログラムカウンタという現在実行している命令が格納されているアドレスを保持するものが参照している場所の命令が実行されます。
メモリに命令を書くと言う感覚は分かりにくいですが、アセンブリをやってみると分かります。

 次に、静的領域です。静的領域は、その名のとおりプログラムの実行中に変化しない変数を格納する領域です。具体的には、グローバル変数やstatic変数が置かれます。この静的領域の大きさはプログラム実行時に確保され固定サイズです。(プログラム実行中にサイズが大きくなったり、小さくなったりしません。)

 そして、ヒープ。ここは、new とか malloc() とかで動的確保するところです。ヒープのサイズはプログラム実行中も変化します。ただし、一般に1つのアプリケーションが使用できるメモリは2GBまでですので、これ以上のサイズのメモリを確保することは普通はできません。

 最後に、スタック。これは局所変数が置かれるところです。スタックのサイズは固定です。このポストの冒頭で書いたように大きなメモリをスタック上に確保すると、すぐにクラッシュします。また、一般にスタックのメモリは大きい方から小さいほうに伸びます。逆にヒープの場合は、小さい方から大きいほうに伸びます。具体的にいうと、スタックの場合は、関数内でint x, int yを宣言した場合、後に宣言したyの方が若いアドレスを持っています。

 んー、ただこれはC言語の構造上のメモリ分類であって、それが物理的にハードウェア上でどのように実現されているかというところまで抑えないと、なんか本質を理解してないような気がする。。
でも、少なくとも上の言葉の分類を知っていれば、技術者同士のコミュニケーションが円滑に進みます。そういう意味では、言葉を覚えるというのは大事ですね。

0 件のコメント:

コメントを投稿