0

私の英語力は非常に低いことに注意してください。しかし、私は説明するために最善を尽くします。


Visual Studio 2008 sp1 で mfc プロジェクトを作成しています。

このプロジェクトには、2008/sp1/native C++ で作成された静的ライブラリが含まれていました

問題はそのステップです:

1) mfc プロジェクトをビルドしてデバッグを開始する
2) メイン ウィンドウの x ボタンまたは alt+f4 をクリックしてプログラムを終了する
3) メイン ウィンドウがすぐに閉じられる
4) しかし、taskmgr のプロセス タブを見ると、まだ生きている。
5) taskmgr で mfc プロジェクト プロセスを強制終了しようとすると、すぐ
に強制終了されます。
7) 時間は 5~10 分
8) ログを出力し、メモリリークを検出!!
9) ログは非常に大きく、テキストはほぼ 11 メガバイトです。


そして私はポイントを見つけます。
1) 静的ライブラリは常に、起動時に new 演算子を使用してライブラリのメイン機能クラスのインスタンスを作成します (起動は静的時間であり、main の前です)
2) 静的ライブラリのコンストラクターには次のコード
ノートがあります: 申し訳ありませんが試してみますこのエディターの「コード」タブを見て、コードセクションを作成できないので、コードを記述して「br」htmlタグを注文します。


VPHYSICS::VPHYSICS(){
       m_tickflowed = 0;
       QueryPerformanceFrequency(&cpu_freq);
       SetTickTime(30);

       m_state[VPHYSTATE_SPEED_MAX]=SPEED_SCALAR_MAX;
       m_state[VPHYSTATE_LIMITED_ACCELARATION]=FALSE;
       m_state[VPHYSTATE_FRICTIONENABLE]=TRUE;
       m_state[VPHYSTATE_FRICTIONFACTOR]=1.0f;
       m_state[VPHYSTATE_GRAVITY]=9.8065f;
       m_state[VPHYSTATE_ENGINESPEED_DELAY_HIGH]=0.0f;
       m_state[VPHYSTATE_ENGINESPEED_DELAY_LOW]=0.0f;
       m_state[VPHYSTATE_FRICTION_RATIO]=1.0f;
       m_state[VPHYSTATE_DIMENSION_GLOBAL]=2;
       m_state[VPHYSTATE_COLLISION_UNFRICTIONABLE]=TRUE;
       m_state[VPHYSTATE_PAULI_EXCLUSION_ENABLE]=TRUE;
       m_state[VPHYSTATE_PAULI_EXCLUSION_RATIO]=1.0f;
       m_state[VPHYSTATE_FRICTION_SMOOTHLY]=1.0f;
       m_state[VPHYSTATE_COLLHANDLER_OUTER]=TRUE;
       m_dwSuspendedCount=0;
       InitializeCriticalSection(&m_criRegister);
       InitializeCriticalSection(&cri_out);
       ZeroMemory(m_objs,sizeof(m_objs));
       m_bThreadDestroy=FALSE;
       m_hPhysicalHandle=0;
       m_nPhysicalThread1ID=0;
       m_nTimeMomentTotalCount=0;
       m_hGarbageCollector=0;
       m_nGarbageCollectorID=0;
       m_PhyProcessIterID=NULL;
       for(DWORD i = 1 ; i < MAX_OBJECT_NUMBER ; i++)
       {
           m_objAvaliable.push_back(i);
       }
  }

//このコードは、ゲームの物理エンジンを使用した静的ライブラリです。

問題は、このインスタンスを破棄するときです。
(プログラムの最後に)削除演算子を呼び出すと、非常に長い時間がかかります。
を外すと

for(DWORD i = 1 ; i < MAX_OBJECT_NUMBER ; i++)
    {
        m_objAvaliable.push_back(i);
    }

、またはMAX_OBJECT_NUMBERを減らします(元は#define MAX_OBJECT_NUMBER 100000でしたが、5または10に減らします)、「長い時間」が消えます!!

'm_objAvaliable' の型はstd::list<DWORD>
です。このメンバー変数はメモリ リークの原因ではないようです。(このコンテナにはヒープ割り当ての関係がないため)
、このライブラリを含む他のプロジェクトにはこの問題はありません。
(ただし、mfcプロジェクトに含まれるのは初めてで、この場合はこの問題しかわかりません)
その問題の解決策を想像できる人はいますか???
詳細が必要な場合は、この記事にコメントしてください。私はできるだけ早く返信し
ます:DEBUGモードでのみ発生します。リリース モードでは、この問題は発生しません。

4

1 に答える 1

0

あなたが経験している問題は、実際にはまったく問題ではないと思います。MFC は独自のデバッグ バージョンをnew使用します (リリース モードでは、通常のデフォルトを使用しますnew)。MFC がこれを行うのは、メモリ リークがあることを知らせるのに役立つようにするためです。

問題は、 MFC が適切に割り当て解除されていないと思われる割り当てをダンプすることを決定したに、静的ライブラリ内のオブジェクトの割り当て解除が発生していると思います。非常に多くのオブジェクトがあることを考えると、これをコンソールにダンプするのに非常に長い時間がかかります。

結局のところ、MFC はメモリ リークが存在しない場合でも存在すると見なします。

あなたの解決策は次のとおりです。

  1. DEBUG NEW を使用して MFC を停止します。である MFC プロジェクト内のすべての行を削除します#define new DEBUG_NEW。この方法の欠点は、もちろん、誤って実際のメモリ リークを作成した場合、それらを追跡できないことです。

  2. 静的ライブラリにある種の初期化、初期化解除関数を用意してください。MFC アプリケーションが終了するとき、MFC がまだ存在していると思われる割り当てのトロールを開始する前に、初期化解除関数を呼び出します。

于 2011-10-26T08:55:56.570 に答える