C言語の基礎
int process(int n) {
int *buf = malloc(n * sizeof(int));
if (buf == NULL) return -1;
if (fill(buf, n) != 0)
return -2;
use(buf, n);
free(buf);
return 0;
}fill と use は別に定義された関数とする。上の関数の問題点として、正しいものはどれか。
- Afill が0以外を返したとき、buf を解放せずに戻るので、確保した領域が解放されないまま残る
- Bmalloc の戻り値を確かめていないので、確保に失敗したときに NULL を参照する
- Cfree の後で buf を使っているので、解放した領域を参照する
答えと解説を見る
正解:A. fill が0以外を返したとき、buf を解放せずに戻るので、確保した領域が解放されないまま残る
malloc で確保した領域は、free で解放するまで残ります。fill が失敗して return -2 で戻る道では free が呼ばれず、buf の値(番地)も失われるので、その領域は二度と解放できません。これをメモリリークといい、関数が繰り返し呼ばれると使えるメモリが減り続けるので、長い間動き続ける組込み機器やサーバでは特に問題になります。戻る前に free(buf) を呼ぶか、解放の処理を関数の最後の1か所にまとめます。
- A. 正しい。エラーで戻る道で free が呼ばれず、メモリリークになります。
- B. malloc の直後に buf == NULL を確かめ、失敗したら -1 を返しています。
- C. free(buf) の後に buf は使われていません。