大量のデータを処理するために,大きな配列をローカル変数で宣言するとコンパイルはで
きても,実行時にエラーとなることがある.例えば,リスト
3のよ
うに,
個の整数型のメモリー領域を使う場合である.実行結
果を見て分かるように,「セグメンテーション違反です」と表示されてプログラムが止まっ
ている.この配列を確保するために必要なメモリーは,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 }
セグメンテーション違反です
大きな配列を使いたい場合,ヒープ領域をつかう.
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 }
a[0]=1
malloc()関数を使って,メモリーを確保している.ただし,この関数でいつも思い
通りのメモリーを確保できるとは限らない.この関数は,メモリー確保に失敗した場合,NULLポ
インターを返す.したがって,教科書のリスト4.8のように,エラー処理を書かなくては
ならない.
C言語では大雑把に言って,コード(code)、データ(data)、ヒープ(heap)、スタック
(stack)の4つの領域にメモリーを分けて,管理する.これらの使い分けに,プログラマー
はほとんど気にする必要はない.ただし,変数--配列や構造体を含む--を使う場合,
メモリーは次のような使い方があると,プログラマーは認識しておくべきである.
-4pt
- 静的変数(static)やグローバル変数,文字列定数などは,メモリーの確保も
解放もしない変数である.これらの変数はデータ領域に格納される.
- 自動変数(auto)の場合,メモリー確保と解放は自動に行われる.自動変数は,
スタック領域に格納される.
- プログラム中でmallocやcalloc関数を使い,ヒープ領域にメモリーの
確保ができる.確保したメモリーを開放する場合には,free()関数
をつかう.
ホームページ:
Yamamoto's laboratory著者:
山本昌志
Yamamoto Masashi
平成19年6月5日