C-PRODUCTION SPECIAL

トップ>特集>mallocの悲劇

■ mallocの悲劇 [2002/03/08]


 今回の号外は、私自身のプログラミングの経験で大失敗した
「ポインタに関係のあるバグ」について書きます。

 まず、どのようなプログラムを書いていたのかというと、外部から呼び
出されてバックグラウンド処理を行うプログラムの一種で、入力される数値を
元に確保するメモリーのサイズを決定し、データ処理するものでした。

 結果として、確保する条件によっては「強制終了」を引き起こすとんでも
ないものを作ってしまいました。
 そもそも、動的メモリ確保を利用したのは少しでもメモリを節約し、更に
データ処理も軽快にしようとしたのですが・・・。

 そのときは開発期間も残り少なく、最大メモリ使用量もある程度わかって
いたので、ガバッと配列でメモリ確保して難を逃れました(爆)

あまり、こんな対処するのはよくないのですが、プログラムで実務をやって
いれば一度はあると思います。(決してあってはいけないと思います。...反省)

 結局、強制終了の元凶を調べてみると、メモリ確保を失敗したときの処理を
記述してないことが、ある条件で強制終了することを見つけました。

 以下に、前回のプログラムより、例外処理をコメントアウトしたものを掲載
します。

#include<stdio.h>
#include<stdlib.h>

main()
{
int n;
char *p;
printf("確保したい領域(文字数) : ");
scanf("%d",&n);

p = (char*)calloc( n+1,sizeof(char) );
// if(p != NULL){
printf("%d文字以内で入力してください : ",n);
scanf("%s",p);
printf("%s が入力されました\n",p);
free(p);
/* }
else printf("メモリの確保に失敗\n");
*/
return;
}

 このプログラムで、メモリ確保に失敗した場合、どうなるでしょうか?
ポインタpが初期化されず非常に危険です。

 そもそも、どういった場合にメモリ確保が失敗するのか未だにわかって
ないのですが・・・(確保する量が少なくても失敗する場合があった)

このpが指し示す、どこかわからない場所でデータ処理を行うわけですから
Win2000/XPではまず「強制終了」されます。

ところが、当初開発に使っていたのがWindowsMeだったのがまずかったのか
テスト段階では強制終了されず、実行されていました。
 多分、その間に沢山のプロセスが破壊されてOSが不安定になってしまい
ますがテストしているプログラム本体は偶然助かっていたわけです。

ポインタが絡むバグはコンパイルしても検出されなければ、実行環境によって
はOSに強制排除される、またはその逆があって大変危険です。

ここで得た教訓は、
1.例外処理はバグのシラミつぶしのつもりで記述
2.システムの処理に期待しすぎない
3.テスト環境はNT系と98系の両方で行う

というものでした。


Copyright© 2000-2006 C-Production All Rights Reserved.