可変長バッファの実装
ご存知のように、C/C++ の「配列」は、コンパイル時に (静的に) そのサイズを決定する必要があります。
そのため、動的配列を扱うには、C では malloc/free 系の関数、C++ では new/delete
そのため、動的配列を扱うには、C では malloc/free 系の関数、C++ では new/delete
[] 演算子を利用することになるわけですが、
- コードが 複雑になる
- 解放の手続きが面倒 (忘れるとメモリリークが発生)
バッファオーバーラン発生の原因は、固定長バッファの仕様、即ち、入力データサイズに対する (不適切な) 上限の仮定にあります。
最近作られた言語では、可変長バッファを利用した入出力機構を (言語使用あるいは標準ライブラリとして) 備えているため、こうした問題が起こることは少ないようです。
それなら、C/C++ でも同じ機構を作ってそれを使えばいいじゃない。というわけで、早速実装してみました。 以下に示したのは C++ での実装ですが、C であれば new/delete
この LoadText 関数を使う際は、戻り値が指す領域を使用後に delete
担当: 成田 (くれぐれも gets は使わないように。)
最近作られた言語では、可変長バッファを利用した入出力機構を (言語使用あるいは標準ライブラリとして) 備えているため、こうした問題が起こることは少ないようです。
それなら、C/C++ でも同じ機構を作ってそれを使えばいいじゃない。というわけで、早速実装してみました。 以下に示したのは C++ での実装ですが、C であれば new/delete
[] 演算子を malloc, free に置き換えればOKです。
#include <stdio.h>
#include <string.h>
#define INIT_BUF_SIZE 32
//ストリームからのテキスト読み込み
char* LoadText(FILE* fp){
if (!fp) return NULL;
int nSize =INIT_BUF_SIZE;
char* lpac =new char [nSize + 1];
int nCount =0;
for (;;){
//読み込み
int nRes =fread(lpac + nCount, 1, nSize - nCount, fp);
if (nRes < nSize - nCount){
nCount +=nRes;
break;
}
nCount +=nRes;
//バッファ拡張
nSize *=2;
char* lpacNew =new char [nSize + 1];
memcpy(lpacNew, lpac, nCount);
delete [] lpac;
lpac =lpacNew;
}
//文字列終端を表すヌル文字 (\0) を付加
lpac[nCount] ='\0';
return lpac;
} |
[] (free) で解放することを忘れないで下さい。
C++ であれば、戻り値を char* を保持するクラス型にして、デストラクタに解放を任せるのがスマートでしょう。担当: 成田 (くれぐれも gets は使わないように。)

コメントを投稿