1

私は練習用のアプリケーションを書くのに少し時間を費やし、何かを削除するのを忘れた場合に備えてメモリリークを回避するために、全体を通してスマートポインタを使用するのが好きでした。同時に、例外を使用してコンストラクターの失敗を報告し、それを処理しようとすることも好きです。ただし、それができない場合は、assert()またはexit()を呼び出して、その場所でプログラムを終了したいと思います。ただし、msvcでcrtdbgライブラリを使用すると、動的に割り当てられたスマートポインタからのメモリリークが報告されます。これは私にとって2つのことのうちの1つを意味します。1)スマートポインタが割り当てられた場所の範囲外に出たり、割り当てを解除したりしてメモリリークが発生したり、2)crtdbgがメインで終了しないために割り当て解除をキャッチしなかったりすることはありません。ただし、ページは_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);を使用します。プログラムの開始時に、任意の出口点からのリークをキャッチしますが、それを使用してもメモリリークエラーが発生します。

皆さんへの私の質問ですが、メモリは実際に終了時またはアサート時に割り当て解除されますか?そうでない場合は、std :: shared_ptrから派生して、呼び出しの直前に割り当て解除される動的に割り当てられたオブジェクトをカタログ化する独自のソリューションを実装できますか?終了またはアサートするのですか、それともより単純なソリューションにはあまりにも多くの作業が必要ですか?

4

2 に答える 2

6

プログラムが終了すると、とにかくメモリはOSによって再利用されるので、リークが心配な場合は、そうすべきではありません。

ただし、デストラクタにロジックがあり、オブジェクトを破棄する必要がある場合、呼び出しexitはすべての割り当て解除を明示的にバイパスします。mainこれの回避策は、exitを呼び出し、それをキャッチして戻るという例外をスローすることです。

#include "stdlib.h"

void foo()
{
   //exit(0);
   throw killException();
}

int main
{
   try
   {
      foo();
   }
   catch (killException& ex)
   {
      //exit program calling destructors
      return EXIT_FAILURE;
   }
}
于 2012-07-30T19:53:24.563 に答える
2

本当の問題はメモリではなく、他のリソースにあります。OSは(組み込みシステムを実行している場合を除いて、ほとんどの場合)プロセスの終了時にプロセスからメモリを回復するため、OSでメモリがリークすることはありません。実際の問題は、プロセスが完了する前に解放する必要がある、プロセスの外部にある他のリソースにある可能性があります...

とにかく、なぜ例外を伝播させるのではなく、それを好むのですabortか?exit一般に、管理したい例外のみを処理し、他の例外を通過させる必要があります。あなたはそれから回復することができないかもしれませんが、あなたの発信者は実際に回復することができるかもしれません。例外をキャプチャしてその場でプログラムを終了することにより、ユーザーから処理の選択肢を取り除くことになります。

于 2012-07-30T19:58:33.987 に答える