こんにちはちゆりです。
今回は上司に
fopenしてるのにfcloseしてないよ。しっかり忘れずにやらなきゃダメでしょ。
と指摘され,C言語におけるfcloseの重要性を考えるいい機会になった。
fopenしたらfclose
そもそもfopenしたらfcloseをするということはC言語におけるお約束ごとであり(Cに限らずどの言語でも..),どの参考書にも「fopenしたらfcloseをしましょう」とは書いてある。そんなこと常識中の常識でありもちろん僕も理解しているし,fcloseはしっかり忘れずにやってきた。...つもり。
僕が指摘されたコードはこんな感じ(さすがに会社のシステムのコードなので改変しています。)
int read_file(void)
{
FILE *fp; // FILE型構造体
char file_name[] = "sample.txt";
char value[20];
//ファイルのopen 読み取りモード
fp = fopen(file_name, "r");
//NULLならリターン
if(fp == NULL)
{
printf("%s file is not open!\n", file_name);
return -1;
}
else
{
printf("%s file is opened!\n", file_name);
}
//ファイルの中身を変数に格納
while(fscanf(fp, "%s", value) != EOF)
{
printf("%s\n",value);
}
//ファイルの中身がPOKEMONじゃなければNGとする。
if(0 != strcmp(value, "POKEMON"))
{
printf("file ERROR!!\n");
return -2;
}
fclose(fp); // ファイルを閉じる
return 0;
}
ほら,ほら。ちゃんと最後の行でfcloseしてるじゃんか。
...と思いきや,注目していただきたいのはこの箇所
//ファイルの中身がPOKEMONじゃなければNGとする。
if(0 != strcmp(value, "POKEMON"))
{
printf("file ERROR!!\n");
return -2;
}
fopenで開いたファイルの中身をチェックし,中身が「POKEMON」じゃなければこの関数を抜けるというものだ。
仮にここでreturnされるとfcloseされずに関数を抜けてしまうのだ。
このように関数の抜け道が1つじゃない場合(最後のreturnだけではない)は抜ける可能性のあるところでfcloseを行わないとマズイ。
今回の場合,return -2の前でもfclose(fp)をしてあげると良い。
fcloseをしないとどうなる
本題は,ここからだ,「そもそもfcloseをしないとどうなるの?」ということだ。
だって,fcloseしなくたって次回もfopenできるもん。参考書にはfcloseをしなさいとは書いてあるけども,あえてfcloseを行わない処理にしてもしっかり動くしfopenもできちゃう。
fclose漏れによるエラーや動作不良なんかでてくれれば,fcloseの重要性が分かるのに。そんなことは教えてくれない。
では,fcloseしないとどうなるのかというのを書いていく。
fopenではメモリを確保します,そしてfcloseではそのメモリを開放します。
仮にfcloseを忘れた場合でも,次にfopenされたらまた別の領域からメモリを確保します。そしてまたまたfcloseを忘れてfopenをした場合はまたまた別の領域からメモリを確保します。fcloseをしないとどんどん空きメモリを消費していくんです。
これを繰り返していくとどうなるのかわかりますよね?メモリの上限に達したら(枯渇したら)もうfopenできなくなるわけですよ。
メモリリークってやつですね。
だから,メモリが十分に空いているときは,fcloseなんかしなくてもいいんです。fopenできるんです。こんなことが可能だからfcloseの重要性というのが分からなくなっていました。
最終的にメモリはmain関数を抜ける(プログラムが終了する)タイミングで全開放されます。お試しサンプルコードとしてmain関数にfopen処理を書いて何百回,何千回繰り返してもfclose漏れによるメモリリークは実現できないのです。
うーん。なかなか難しい。
最後に
今回の上司からの指摘でfcloseの重要性を存分に知った。趣味程度のプログラムを作る上では大きな影響はないが,莫大なシステムを作る上では非常に重要なお作法なのだと痛感しました。最近はPCやマイコンも大きなメモリで動きますし,「メモリがメモリが」と常にメモリを意識したコードを組まなくても良い時代となりましたね。(もちろん意識は必要ですが)
メモリを確保したら(fopenしたら)しっかり忘れずに開放してあげる(fcloseしてあげる)というのを意識しようとアドバイスです。
fclose=社畜生活を送ること
あなたは給料を貰っていますよね(fclose)。日々の出費でお金はなくなって行きます(fopen)。でも,来月には給料をもらえます(fclose)。仕事を辞める=fclose漏れなのですわ。
出費ばかりになり(fopen),お金が尽きれば(メモリが枯渇)もう出費できるお金がないのです(fopenできない)。だから,僕のように社畜な日々を送り,お金を稼ぎましょう。(fcloseしましょう)
あ,でもあなたの場合はお金を稼いでも稼いでも出費のほうが多いですから,仕事をしていてもお金が減る一方ですよね。うーん,残念。メモリリーク!!
お後がよろしいようで。ばいちゃ。
C言語おすすめ書籍
僕のC言語のおすすめ書籍を紹介しておきます。難易度はやや高めなので入門書として購入するのはあまりおすすめできませんが,C言語をある程度勉強された方には非常にタメになる一冊です。これさえ理解できれば怖いものなしです。ぜひ。
★次に読んでほしい記事
コメント