第33章 メモリの動的確保  


今回は、メモリの動的確保についてやります。メモリの動的 確保とはどういうことかというと、たとえばプログラムを 書いている時点ではどのくらいの配列が必要なのかわからない 場合がよくあります。あらかじめ、巨大な配列を用意 しておくというのも一つの解決策ではあります。でも、 プログラムが終了するまでその配列用のメモリは確保され続け 他の用途に使えません。

それは、資源の無駄遣いだ!

その通りです。 必要なときに、必要なだけ確保できればこれに超したことはありません。 では、メモリを動的に確保するときによく使う関数を 2つほど紹介いておきます。

#include <stdlib.h> void *calloc(size_t num, size_t size); #include <stdlib.h> void *malloc(size_t size);

callocは、大きさがsizeバイトのnum個の記憶領域を確保します。
mallocは、大きさがsizeバイトの記憶領域を確保します。

これじゃさっぱりわからん!

size_tというのは一体なんだ?!

そういえば昔time_tとかいうのが出てきたな・・・ (第13章第26章)

time_tというのとは、関係ありません。これは、sizeof演算子や、strlen関数の 結果の型です。筆者の使っているVC++1.51のstdio.hをのぞくと次のように 定義されています。

typedef unsigned int size_t;
しかし、違う処理系では必ずしもunsigned int型ではありません。 (具体的にどれがどうだということは筆者は知りません。int型とかlong型 という処理系もあるらしいです)そこでsize_tと言う型を決めたという ことです。一度自分の持っている処理系のstdio.hをのぞいてみてください。 当たり前ですがstdio.hを編集しないでください。

それと、この2つの関数の戻り値がvoid *型というのはわかりますか?

これは、簡単にはこの関数の返す値をどんな型にでも変換できますよ、 というくらいの意味にとらえておいてください。

具体的には、どうすりゃいいの?

はい、型キャスト(cast)というのを行います。castとは、型にはめ込むという 英語です。ですからギプス(骨折したときに使いますね)のことを英語でcast といいます。(本当かね??)また、配役のこともcastと言います。その役に 俳優をはめ込むという意味だと思います。どうです、このホーム・ページは 英語の勉強にもなるでしょう。

変換したい型をカッコでくくってやればいいのです。

(long)x

などのように使います。

では、メモリの動的な確保の具体的プログラムを見てみましょう。 その前に、ポインタと配列の関係を勉強したばかりの超初心者 の陥りやすい間違いから見てみることにしましょう。

これは、変ですね。int型へのポインタを宣言しただけなのに あたかも何かすでに配列が存在しているかのような使い方です。 ポインタというのは、あくまでもすでにある変数等のアドレスを格納するもので こういう使い方はありません。コンパイルすると当然warningがでます。 しかし、errorにはなりませんので、exeが作られてしまいます。 しかし、絶対に実行してはいけません。何が起こるかわかりません。

上のプログラムを正しくするには左のようにメモリを動的に確保してやります。 int型の大きさを持つメモリが連続してどこかに4個確保されます(配列が 確保されたと考えてよい)。 そして、この確保されたメモリの先頭のアドレスがbufに格納されます。 2番目のメモリは(buf+1)にありますね。この時buf+1バイト先のメモリ という意味ではなくbuf番地よりint型の大きさ1個分先のメモリという意味です。 このへんは、配列とポインタの章をよく読んでみてください。

そして、大事なことは 自分で確保したメモリは、自分で解放してください (free関数)。また、callocで確保された要素は0で初期化されています。

次にmalloc関数ですが単純に確保したい領域の大きさのみを引数に取ります。 calloc関数と違い0で初期化されることはありません。筆者はDOSのプログラムで アニメーションを作るときによくこの関数を使います。いずれにせよ、ポインタの 使い方は非常に重要ですので、何回も復習しておいてください。 (と、いう筆者も時々間違った使い方をしてひどい目にあっています。)


[Index][総合Index] [Previous Chapter] [Next Chapter]

Update Nov/27/1996 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。