3 動的なメモリーの確保

3.1 スタック領域のメモリー割り当ては小さい

大量のデータを処理するために,大きな配列をローカル変数で宣言するとコンパイルはで きても,実行時にエラーとなることがある.例えば,リスト3のよ うに, $ 1024\times1024\times10$個の整数型のメモリー領域を使う場合である.実行結 果を見て分かるように,「セグメンテーション違反です」と表示されてプログラムが止まっ ている.この配列を確保するために必要なメモリーは,40[Mbyte]である.このプログラ ムを実行したPCのメモリーは1[Gbyte]である.このように大きなメモリーをあるにかかわ らず,たった40[Mbyte]がユーザーが使えないなんて,おかしい!!

大きなメモリー使えない理由は,スタック領域が狭いことによる.先に述べたようにロー カル変数はスタック領域を使うため,それに制限されるのである.大きなスタック領域を 用意するわけにもいかない.これは,様々なプログラムのローカル変数が使う場所で,こ こに大きな領域を用意すると,プログラム領域などが不足する.大きなスタック領域を用 意しても,ほとんどの場合は使われないだろう.

   1 #include <stdio.h>
   2 
   3 int main(void)
   4 {
   5   int a[1024*1024*10];
   6 
   7   a[0]=1;
   8   printf("a[0]=%d\n",a[0]);
   9 
  10   return 0;
  11 }


\fbox{実行結果}
セグメンテーション違反です

3.2 mallocfree

大きな配列を使いたい場合,ヒープ領域をつかう.malloc()関数によりメモリーを 確保して,free()関数によりメモリーを開放する.その例をリスト 4に示す.
   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 
   4 int main(void)
   5 {
   6   int *a;
   7 
   8   a=malloc(sizeof(int)*1024*1024*10);
   9 
  10   a[0]=1;
  11   printf("a[0]=%d\n",a[0]);
  12 
  13   free(a);
  14 
  15   return 0;
  16 }


\fbox{実行結果}
a[0]=1

malloc()関数を使って,メモリーを確保している.ただし,この関数でいつも思い 通りのメモリーを確保できるとは限らない.この関数は,メモリー確保に失敗した場合,NULLポ インターを返す.したがって,教科書のリスト4.8のように,エラー処理を書かなくては ならない.

3.3 メモリー配置

C言語では大雑把に言って,コード(code)、データ(data)、ヒープ(heap)、スタック (stack)の4つの領域にメモリーを分けて,管理する.これらの使い分けに,プログラマー はほとんど気にする必要はない.ただし,変数--配列や構造体を含む--を使う場合, メモリーは次のような使い方があると,プログラマーは認識しておくべきである. -4pt


ホームページ: Yamamoto's laboratory
著者: 山本昌志
Yamamoto Masashi
平成19年6月5日


no counter