質問
atexit()関数でメモリを解放するポイントはありますか?
起動後にmallocされるグローバル変数があります。解放するためにatexit()関数を書くことはできますが、プログラムがとにかく終了したとき、システムはそのメモリをすべて回収しませんか?
整頓して積極的に自分で掃除することには何か利点がありますか?
解決
Cではありません-船があなたの周りに沈む間にデッキチェアを再配置するようなものです。
C ++では、オブジェクトがデストラクタ内の一時ファイルなどを削除できるため、答えは異なります。そのため、それらが呼び出されることを確認する必要があります。
他のヒント
それを解放する利点の1つは、プロセスの存続期間にわたって割り当てと割り当て解除を一致させようとするメモリリークテストを行った場合、この種の意図的なリークから誤検知が発生しないことです。
malloc()
/ free()
として見ると、通常、ユーザー空間に存在する広範なデータ構造が含まれ、 free()
プログラムの終了は、実際にはパフォーマンスの低下になる可能性があります。データ構造の一部がディスクにページングされる場合、ディスクからロードする必要があるのは破棄するだけです!
free()
なしで終了した場合、ディスクにページアウトされたデータは安心して死ぬ可能性があります。
もちろん、他の時間に free()
することは、さらに多くの malloc()
が解放したスペースを再利用でき、 free()
は、他のプロセスが使用できるメモリのマッピングを解除することもあります。
最新のすべてのオペレーティングシステムでは、プログラムの終了時にすべてのメモリが解放されると安全に想定できます。
実際に整頓されていると、プログラムが進化するときに興味深いことがあります。「初期化」を作成するときに、クリーンアップ関数を書く必要があります。関数。プログラムがより複雑になり、プログラムの一部を再起動したい場合に利点があります。既に機能するクリーンアップ関数を作成している場合、「再起動」時に突然クリーンアップを忘れてしまう可能性は低くなります。プログラムの一部。
クリーンアップ関数の作成" lazily&quot ;;つまり、必要な場合のみエラーが発生しやすくなります。クリーンアップ関数を作成すると、クリーンアップと最終的なクリーンアップ依存関係について考える必要があります。コードの一部を別のプロジェクトで簡単に再利用できます。
したがって、はい、atexitでの解放は役に立たないので、ファイル記述子を閉じます。ただし、コードが大きくなるにつれてクリーンアップ関数を記述して維持することは、何をしているのかを考えることを余儀なくされる制約になる可能性があります
atexit()を呼び出しているコードが動的にロードされた共有ライブラリの一部である場合(たとえば、dlopen()を使用して)free()する必要があります。この場合、atexitハンドラーはdlclose()時に呼び出されるため、残りのプロセスが使用するためにヒープが存在し続けます。
Windowsでは、一部の呼び出しはOSまたはCOMに属するメモリを返すため、そのメモリを明示的に解放する必要があります。そうしないと、プロセスが終了しても解放されません。しかし、これはまれなシナリオです。
プロセスの終了前にメモリを解放しないことは、メモリリークではありません。ハンドルを失うとメモリリークになります。しかし、メモリはリソースの唯一のタイプではなく、他のリソースはプロセス間(ウィンドウハンドルやファイルハンドルなど)で保持されるため、それらを「解放」する必要があります。