14

重複の可能性:
C アプリケーションを終了すると、malloc されたメモリは自動的に解放されますか?

この質問は、C/C++ での動的メモリ割り当てに関して、delete/free をそれぞれ使用することがどのように義務付けられているかについて読んでいたときに頭に浮かびました。プログラムの実行が終了してもメモリ割り当てが持続する場合は、必須だと思いました。それ以外の場合、割り当てられたスペースを解放することを心配する必要があるのはなぜですか? プロセスの終了で OS が自動的に解放するのではないですか? 私はどのくらい正しいですか?私の質問はそれができるということです

int *ip = new int(8);

プログラムの終了後も持続しますか?

4

9 に答える 9

15

簡単な答え: いいえ。

長い答え: いいえ。C++ は、そうするように作業を行わない限り、メモリを永続化することはありません。メモリを解放する理由は次のとおりです。

メモリを解放せずに割り当て続けると、ある時点でメモリが不足します。使い果たしたら、ほとんど何でも起こり得ます。Linux では、おそらく OOM キラーがアクティブになり、プロセスが強制終了されます。たぶん、OS が完全にディスクにページングします。十分なメモリを使用している場合は、Windows ボックスにブルー スクリーンを表示することがあります。これは、ほとんど未定義の動作と考えることができます。また、メモリをリークした場合、それはそこに置かれ、未使用で解放されず、プロセスが終了するまで誰も使用できません。

別の理由もあります。メモリをアロケータに解放すると、アロケータはメモリを保持する可能性がありますが、使用可能としてマークするだけです。これは、次にメモリが必要になったときに、メモリがすでにそこにあることを意味します。つまり、メモリを要求するカーネルへの呼び出しが少なくなり、パフォーマンスが向上します。これは、コンテキスト スイッチが非常に非効率であるためです。

編集: C および C++ 標準では、終了後にメモリが OS によってクリーンアップされるという保証さえありません。多くの OS とコンパイラはそうかもしれませんが、保証はありません。それにもかかわらず、すべての主要なデスクトップおよびモバイル オペレーティング システム (おそらく DOS と一部の非常に古い組み込みシステムを除く) は、その後プロセス メモリをクリーンアップします。

于 2012-07-08T13:17:12.953 に答える
6

プログラムが終了する前にメモリを解放して OS に戻す必要はありません。これは、オペレーティング システムがプロセスの終了時にプロセスに割り当てられたすべてのメモリを再利用するためです。プロセスの完了までに必要なオブジェクトを割り当てた場合、それを解放する必要はありません。

そうは言っても、いずれにせよメモリを解放することは良い考えです。プログラムが動的メモリを大量に使用する場合、ほぼ確実にメモリ プロファイラを実行してメモリ リークをチェックする必要があります。プロファイラーは、最後に解放しなかったブロックについて通知します。それらを無視することを忘れないでください。コンパイラの警告を 100% 排除するのと同じ理由で、リークの数を 0 に保つ方がはるかに優れています。

于 2012-07-08T13:17:44.413 に答える
5

歴史的なメモ:古いAmigaコンピュータ(「AmigaOS」)で使用されていたオペレーティングシステムは、現在想定されているように完全なメモリ管理を備えていませんでした(Amigaが普及しなくなったときにリリースされた新しいバージョンを除く)。

CPUにはMMU(メモリ管理ユニット)がなく、その結果、すべてのプロセスがすべての物理メモリにアクセスできました。そのため、2つのプロセスが情報を共有したい場合は、ポインターを交換するだけで済みます。この方法は、メッセージパッシングスキームでこの手法を使用したOSによっても奨励されました。

ただし、これにより、どのプロセスがメモリのどの部分を所有しているかを追跡できなくなりました。そのため、OSは終了したプロセス(または実際には他のリソース)のメモリを解放しませんでした。したがって、割り当てられたすべてのメモリを解放することが重要でした。

于 2012-07-08T14:50:37.087 に答える
5

1)ヒープ外の場合は、リクエスト時にメモリを解放します。メモリリークは決して良いことではありません。それが今あなたを傷つけないなら、それはおそらく将来的に起こります.

2) C または C++ では、OS がメモリをクリーンアップするという保証はありません。いつの日か、実際にはそうではないシステムでプログラミングをしているかもしれません。さらに悪いことに、メモリ リークを気にしないコードをこの新しいプラットフォームに移植している可能性もあります。

于 2012-07-08T13:18:54.427 に答える
4

適切な OS は、プロセスの終了時にすべてのリソースをクリーンアップする必要があります。「割り当てたものは常に解放する」という原則は、次の 2 つの点で有効です。

  1. プログラムがメモリ リークを起こしても終了しない場合 (デーモン、サーバーなど)、継続的にメモリ リークが発生すると、RAM が大幅に浪費されます。

  2. プログラムが終了するまですべてのメモリの解放を遅らせるべきではありません (Firefox が時々行うように - 終了するのにどれだけ時間がかかるか気付きましたか?) - ポイントは、メモリを割り当てた時間を最小限に抑えることです。プログラムが引き続き実行されている場合でも、作業が終了したらすぐに割り当てられた RAM を解放する必要があります。

于 2012-07-08T13:16:51.667 に答える
4

プログラムの存続期間中にメモリを解放する必要がないと確信している場合は、技術的には解放/削除をスキップしても問題ない場合があります。Linux、Windows などのオペレーティング システムは、プロセスが終了すると、割り当てられたメモリを解放します。しかし実際には、割り当てたメモリをプロセスの存続期間内に解放する必要がないと仮定することはほとんどできません。コードの再利用性、保守性、および拡張性を念頭に置いて、適切な場所に割り当てたすべてのものを常に解放することをお勧めします。

于 2012-07-08T13:20:58.647 に答える
2

これは興味深い質問です。あなたの質問に対する私の最初の見解は、プログラムの完了後にメモリにアクセスできるかどうかでしたが、2 回目の読み取りの後、メモリを解放する必要がある理由を知りたがっていることがわかります。

動的に割り当てられたメモリを解放しないと、OS や他のプロセスが不足し、再起動する必要があるためです。

プログラムの完了後にそのメモリにアクセスしたいかもしれないと思ったので、動的に割り当てられたメモリブロックの開始アドレスと長さをコンソールまたはファイルに書き出しても、そのアドレスは有効ではない可能性があると思いますプログラム終了後。

これは、プログラムの実行中に仮想ページ アドレスがあり、プログラムの完了後にカーネル権限がないとアクセスできない可能性があるためです。または、別の理由があります。

于 2012-07-08T13:15:17.553 に答える
1

それは確かにプログラムの終了を超えて生き残ることはできません. プログラムがメモリを無駄にしないように (実際に必要以上に消費しないようにするため)、さらに悪いことに (割り当てパターンによっては) メモリが不足しないようにするためです。

于 2012-07-08T13:17:14.280 に答える
0

多くの場所に多くのメモリを割り当てていて、それを解放していないと想像してください。メモリが割り当てられると、それ以上割り当てることができないメモリの一部を占有します。これにより、解放に失敗しているため、使用可能なメモリの量が毎回小さくなります。ある時点で、メモリは使い果たされます。プログラムの終了時にメモリが解放されたとしても、プログラムが一度に数週間実行され、絶えずメモリが割り当てられ、解放されることはないと想像してください。メモリは有限のリソースであり、動的割り当てを使用する場合は責任を負う必要があります。

于 2012-07-08T13:14:47.503 に答える