ヒープ領域とスタック領域の違いを解説

プログラミング知識

メモリの領域にはヒープ領域とスタック領域があります。両方同じメモリ領域ではありますが、管理や使われ方に違いがあります。

今回はヒープ領域とスタック領域について解説していきます。

ヒープ領域とスタック領域

ヒープ(heap)領域もスタック(stack)領域もメモリ領域の呼び方です。

一般的にプログラムのメモリ領域はこのように取られます。これはプログラムごとにOSによって確保されます。

「プログラム管理用領域」と「静的変数領域」はOSが管理している領域です。「ヒープ、スタック領域」と書かれている領域がプログラムで使用できる領域になります。

ここで低位アドレスは小さいアドレス、高位アドレスは大きいアドレスになります。たとえば0x0000と0xffffなら0x0000が低位、0xffffが高位です。

ヒープ、スタック領域内で、ヒープメモリは低位アドレス側から、スタック領域は高位アドレス側から増えていきます。

ヒープもスタックも積むという意味です。

ではヒープ領域とスタック領域の違いはなんでしょうか。

スタック領域

スタック領域は通常の変数の領域です。auto変数などとも呼ばれますが、変数を定義するとスタック領域に確保されます。

char str[256]; int i; float f;
Code language: CSS (css)

このように記述するとスタック領域に、256byte、4byte、4byteと積まれていきます。

スタック領域に積まれた変数は、OSが自動的に必要な時に確保して、使用しなくなったら開放してくれます。

スタックはプログラムをコンパイルする時点でサイズが決まるため、動的に使用したいサイズが変わるときには想定できる最大サイズを確保しておく必要があります。これではメモリの無駄遣いになるため、ヒープというものが出てきます。

ヒープ領域

ヒープ領域はアプリケーションが動的に確保する領域です。C言語においては一般的にmalloc関数で確保します。

char *data; int size = 256; data = malloc(size); free(date);

このように記述するとヒープ領域が256byte確保でき、確保した領域の先頭アドレスがdataに格納されます。free関数で確保したヒープ領域が解放されます。

スタックとは違い、sizeは可変にすることができます。コンパイル時点ではサイズが決まっていない場合に有効です。たとえばファイル読み込みやネットワークでデータを受信するときなど、実行してみないとサイズが分からない場合はヒープを使用します。

ヒープを使用するときの注意点

mallocでヒープ領域を確保した時は、かならずfreeで開放しましょう。解放ぜずにmallocし続けるとメモリリークとなります。

メモリリークは常駐プログラムの天敵です。少し動かしただけでは正常に動いているように見えても、1年など長期間動かしたときに、突然メモリ枯渇して落ちるといった障害を引き起こします。

メモリリークは試験ではなかなか見つけることができないので、解析ツールなどを使って見つけていきます。

ヒープの確保・解放を繰り返すとメモリが断片化(フラグメンテーション)され、使用できないメモリが増えていきます。ヒープの確保・解放は最小限にしましょう。

メモリとメモリの間には小さなすき間が発生します。これが何度も繰り返されるうちに使用できない領域が増えてしまうという現象が発生します。見かけ上はメモリが潤沢にあるのに使用できるサイズが少ないという状況におちいってしまいます。

まとめ

ヒープ領域
  • プログラムが実行時に動的にサイズを確保するメモリ領域
  • プログラム自身が確保・解放を管理する必要がある
スタック領域
  • コンパイル時点でサイズが確定するメモリ領域
  • OSが自動的に必要な時に確保、不要になったら解放してくれる

コメント

タイトルとURLをコピーしました