みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

動的メモリとexit(C言語)

fpA=fopen("name1", "r");
fpB=fopen("name2", "r");
fpC=fopen("name3", "r");
if(fpA==NULL || fpB==NULL || fpC==NULL){
exit(1);
}
fpAとfpBのファイルオープンに成功してfpCで失敗した場合、exit(1)によってfpAとfpBはクローズされますよね?

じゃあ、
a=malloc(size);
b=malloc(size);
c=malloc(size);
if(a==NULL || b==NULL || c==NULL){
exit(1);
}
aとbのメモリ確保に成功してcで失敗した場合、aとbのメモリはどうなっちゃうんでしょう?exitは動的メモリも解放してくれるのですか?

とりあえず以下のようにしてますが…。
a=malloc(size);
b=malloc(size);
c=malloc(size);
if(a==NULL || b==NULL || c==NULL){
free(a); free(b); free(c);
exit(1);
}

投稿日時 - 2008-03-07 20:05:18

QNo.3841869

困ってます

質問者が選んだベストアンサー

最近の普通の OS、Windows や Linux, Mac OSX などでは、プログラムの実行が exit() などで終了すると、そのプログラムの実行で使われていた「資源」をできるだけ使われていなかった状態に戻す、ということをします。これを「資源の開放」と呼んでいます。

ファイルもメモリも OS の概念としては資源という扱いになっていて、後始末を OS が自動的にやってくれます。ですから、fopen() したファイルや malloc() で確保したメモリは、プログラムの終了とともに、プログラム開始前の状態、ファイルだったらクローズ、メモリだったら開放されます。

もしそうしなかった場合、以前に実行したプログラムの影響が残って、次に動かすプログラムの実行に影響が生じる可能性があります。

またこの後処理は exit() の中で行われるのではなく、あくまで OS がプログラムの終了を見張っていて、終了した場合に必ず行われます。もし exit() の中で後処理をしていたとすると、プログラムが異常終了した場合、exit() は呼び出されませんので後処理が行われなくなってしまいます。

このように。プログラム終了時の動作は言語の仕様というよりも OS の仕様です。ですから No.1 さんのおっしゃるように言語仕様としては定義ができないのです。例えば MS-DOS のような「ちゃんとした OS」 ではない場合、開放してくれない場合があったりします。

蛇足ながら、No.2 さんがおっしゃる「共有メモリ」というのは、複数のプログラムの間でデータをやり取りするための特殊なメモリ領域のことです。複数のプログラムから参照されるため、ひとつのプログラムが終了しても他のプログラムから参照している(その時は参照されていなくても、将来参照される可能性がある)ので、開放できないのです。

投稿日時 - 2008-03-08 22:36:18

お礼

どうもありがとうございました。

投稿日時 - 2008-03-10 19:01:30

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

Cのプログラムでは、なにかしなくてはならない事柄については、細かく規格が制定されています。
一方、規格上では決められていにもかかわらず、なにかしなければならないことがあるという事例は聞いたことがありません。

そして、規格上は、mallocしたメモリをfreeしなければならない、とはどこにも書いていません。

ということは、mallocしたメモリをfreeせずにexitした場合でも、プログラムは正常に動作すると解釈できると思います。

投稿日時 - 2008-03-10 13:20:48

補足

ありがとうございました。

投稿日時 - 2008-03-10 19:02:31

ANo.4

ちなみにファイルに関しては、abort等で異常終了した場合を除き、プログラム終了時にクローズされることが言語規格上保証されています。
ただし、それはfopen, freopen, tmpfileでオープンしたファイル、およびstdin, stdout, stderrの話であって、非標準関数を用いてオープンしたものは別です。

投稿日時 - 2008-03-10 12:53:04

ANo.2

mallocで割り付けたメモリブロックが、exit関数の呼び出しでどうなるかは、規格上は何も規定されていません。
また、プログラムの終了の具体的な意味も処理系定義です。

処理系を特定していない以上、一般論としては何も保証されないとしかいえません。

投稿日時 - 2008-03-08 00:58:14

お礼

ありがとうございました。

投稿日時 - 2008-03-10 18:59:23

ANo.1

mallocは自アドレス空間に確保されたページを
飽くまでもライブラリレベルでサブアロケーション
しているだけですよ。
共有メモリではないんで当然開放されます。

投稿日時 - 2008-03-07 20:53:50

お礼

安心しました。ありがとうございました。

投稿日時 - 2008-03-10 18:57:32

あなたにオススメの質問