fgets関数などで一行分の文字列を読み込む場合など、サイズが分からないデータを格納するための配列の要素数はどのようにしているでしょうか? 実際に入力されるデータの長さは分からないまでも、プログラムが必要としている長さの上限が分かるのであれば、それを配列のサイズにすればよいでしょう。しかし、とりあえず大きめに取っておこうという場合が問題です。
そのような場合によく見かけるのが、BUFSIZマクロを配列の要素数またはバイト数に使うというものです。実際、
0 1 2 3 |
char s[BUFSIZ]; fgets(s, BUFSIZ, stdin); |
のようなコードを目にする機会は少なくありません。しかし、これはBUFSIZマクロの誤用といわざるを得ません。
まず、BUFSIZマクロとは何かから見ていきましょう。これは、setbuf関数に渡す配列のサイズを表すためのマクロで、標準規格では、その値は256バイト以上と定められています。実際の処理系では、512バイト~8192バイト程度に定義されているようです。ですので、BUSIZマクロの本来の使い方は次のようになります。
0 1 2 3 4 |
FILE *stream = fopen(path, "r"); char buffer[BUFSIZ]; setbuf(stream, buffer); |
BUFSIZマクロの値は、ファイルシステムから一度にデータを読み込むのに適したバイト数になっていることが多いのですが、使用できるメモリ量との兼ね合いから妥協点を見出している場合もあれば、複数のファイルシステムが混在するような環境もあるため、一概にはいえません。また、8192バイトもの配列を安易に自動記憶域期間に割付けるのもどうかと思います。
この値は、ファイルシステムから一度にデータを読み込むのに適したバイト数になっていることが多いのですが、使用できるメモリ量との兼ね合いから妥協点を見出している場合もあれば、複数のファイルシステムが混在するような環境もあるため、一概にはいえません。また、環境にもよりますが、8192バイトもの配列を安易に自動記憶域期間に割付けるのもどうかと思います。
仮に、本当にファイルシステムから一度にデータを読み込むのに適したバイト数だったとしても、それを根拠に配列のサイズを決定するぐらいであれば、いっそのこと、setbuf関数またはsetvbuf関数を用いてストリームのバッファリングを無効にし、自分でバッファリングを制御した方がよいでしょう。