callocは、大きさがsizeバイトのnum個の記憶領域を確保します。#include <stdlib.h> void *calloc(size_t num, size_t size); #include <stdlib.h> void *malloc(size_t size);
そういえば昔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 *型というのはわかりますか?
これは、簡単にはこの関数の返す値をどんな型にでも変換できますよ、 というくらいの意味にとらえておいてください。
変換したい型をカッコでくくってやればいいのです。
(long)x
などのように使います。
では、メモリの動的な確保の具体的プログラムを見てみましょう。
その前に、ポインタと配列の関係を勉強したばかりの超初心者
の陥りやすい間違いから見てみることにしましょう。
これは、変ですね。int型へのポインタを宣言しただけなのに
あたかも何かすでに配列が存在しているかのような使い方です。
ポインタというのは、あくまでもすでにある変数等のアドレスを格納するもので
こういう使い方はありません。コンパイルすると当然warningがでます。
しかし、errorにはなりませんので、exeが作られてしまいます。
しかし、絶対に実行してはいけません。何が起こるかわかりません。
上のプログラムを正しくするには左のようにメモリを動的に確保してやります。 int型の大きさを持つメモリが連続してどこかに4個確保されます(配列が 確保されたと考えてよい)。 そして、この確保されたメモリの先頭のアドレスがbufに格納されます。 2番目のメモリは(buf+1)にありますね。この時buf+1バイト先のメモリ という意味ではなくbuf番地よりint型の大きさ1個分先のメモリという意味です。 このへんは、配列とポインタの章をよく読んでみてください。
そして、大事なことは
自分で確保したメモリは、自分で解放してください
(free関数)。また、callocで確保された要素は0で初期化されています。
次にmalloc関数ですが単純に確保したい領域の大きさのみを引数に取ります。
calloc関数と違い0で初期化されることはありません。筆者はDOSのプログラムで
アニメーションを作るときによくこの関数を使います。いずれにせよ、ポインタの
使い方は非常に重要ですので、何回も復習しておいてください。
(と、いう筆者も時々間違った使い方をしてひどい目にあっています。)
Update Nov/27/1996 By Y.Kumei