割り当てられたメモリを削除/解放で解放しないと、メモリリークが発生することを私は知っています。私の質問は次のとおりです。プログラムが終了した場合、オペレーティング システムは解放していなくてもメモリを解放してくれますか?
5 に答える
要するに、はい。
プロセスのアドレス空間にマップされたすべてのストレージは、明示的に解放していなくても、そのプロセスが終了するとオペレーティング システムに返されます。
C++ では、delete を実行すると、オブジェクトのデストラクタが呼び出されます。このデストラクタは、メモリの解放以外の処理を行う場合があります。ファイルを閉じたり、参照カウントを減らしたりする可能性があります。したがって、動的に割り当てられたオブジェクトを削除しないと、何が問題になるかわかりません。
メモリ リークが発生するかどうかは、オペレーティング システムによって異なります。ほとんどのオペレーティング システムの場合、プログラムが実行されているプロセスが終了すると、OS はプロセスに割り当てられたメモリを単に再利用します。
それには別の重要な側面があります。new
クラス コンストラクターdelete
が呼び出され、デストラクタが呼び出されます。したがって、呼び出して呼び出したことがない場合、プログラムの終了後に存在する可能性がある、または存在しない可能性がある、new
いわゆるメモリ リークdelete
に加えて、特定のクラスのデストラクタが副作用のあるコードを呼び出す場合、次のような追加の条件があります。未定義の動作。
したがって、答えは場合によって異なります。次の可能性があります。
- メモリ リーク ( OS の動作に依存)
- 未定義の動作 (デストラクタのコードに副作用があるかどうかによる)
C++11 標準 3.8 オブジェクトの有効期間:
パラ 4:
プログラムは、オブジェクトが占有するストレージを再利用するか、非自明なデストラクタを使用してクラス型のオブジェクトのデストラクタを明示的に呼び出すことにより、オブジェクトの有効期間を終了できます。自明でないデストラクタを持つクラス型のオブジェクトの場合、プログラムは、オブジェクトが占有するストレージが再利用または解放される前に、デストラクタを明示的に呼び出す必要はありません。ただし、デストラクタへの明示的な呼び出しがない場合、またはストレージを解放するために削除式 (5.3.5) が使用されていない場合、デストラクタは暗黙的に呼び出されてはならず、デストラクタによって生成される副作用に依存するすべてのプログラム未定義の動作があります。
呼び出さない場合delete
- デストラクタは呼び出されません。デストラクタがファイルを閉じたり、データベースに何かを書き込んだりすると、これらのアクションは実行されません
あなたの質問は、メモリがどのように機能するかについての素朴な理解に基づいているようですが、それは最新のオペレーティング システムの機能に対応していません。「メモリ」という用語は紛らわしいほどあいまいです。実際には、物理メモリ (RAM) と仮想メモリ (アドレス空間) を別々に考える必要があります。
を呼び出すときmalloc
は、プロセスでアドレス空間を予約します。オペレーティング システムは、そうすることが賢明であると判断した場合、そのアドレス空間を物理 RAM でバックアップします。OS がその RAM を別の用途に使用したい場合は、単純に使用します。あなたはそれを止めることはできません。したがって、RAM について心配する必要はありません。オペレーティング システムは、プロセスによって特別に解放されなくても、常に RAM を最大限に活用できるほどスマートです。
単なるアドレス空間である仮想メモリは不足しているわけではありません。また、プロセスが終了するとすぐに、アドレス空間は存在しなくなります。したがって、返すものは何もありません。
メモリにアクセスできなくなるとすぐに、オペレーティング システムはメモリを解放するしかありません。