1

メモリをリークしない基本的なwxWidgetsプログラムを作成しようとしています(Windows 7で開発しており、Visual Studio 2010を使用しており、CRTを使用してリークをチェックしようとしています)。

私はOpenGLサンプルから始めて、徐々にそれを減らしていきました。wxAppオブジェクトのOnExitメソッドにCRT呼び出しを追加した後(私がこれまでに言及した唯一の場所)、メモリがどこでもリークされていることに気付きました。

このサンプルコードを作成するまで、徐々に作業を進めていきました。これにより、CRTは大量のリークを吐き出します。

#include <wx/glcanvas.h>
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

#ifdef __WXMSW__
#include <wx/msw/msvcrt.h>
#endif
#if !defined(_INC_CRTDBG)// || !defined(_CRTDBG_MAP_ALLOC)
    #error "Debug CRT functions have not been included!"
#endif

class App : public wxApp {
    public:
        bool OnInit(void);
        int OnExit(void);
};
bool App::OnInit(void) {
    if (!wxApp::OnInit()) return false;
    return true;
}
int App::OnExit(void) {
    return wxApp::OnExit();
}

int WINAPI WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance, wxCmdLineArgType cmd_line, int cmd_show) {
    int leaks = _CrtDumpMemoryLeaks();
    if (leaks) {
        int i=0, j=6/i; //Put a breakpoint here or throw an exception
    }

    return EXIT_SUCCESS;
}

#pragma comment(lib,"wxbase29ud.lib")
#pragma comment(lib,"wxmsw29ud_gl.lib")
#pragma comment(lib,"wxmsw29ud_core.lib")
#pragma comment(lib,"wxpngd.lib")
#pragma comment(lib,"wxzlibd.lib")
#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"rpcrt4.lib")

クラスAppはどこでも使用されていないことに注意してください。クラス外の関数定義は、最適化されないようにするために必要です。クラスAppが存在しない場合、エラーは発生しません。

問題は、なぜこれが機能しないのかということです。リークのないwxWidgetsプログラムを作成するにはどうすればよいですか?_CrtDumpMemoryLeaks()はどのように使用すればよいですか?なぜこれに関するリソースがないのですか?もしあれば、どこにありますか?私が見つけた最高のものはこれでした。これはCRTの使用を提案するだけでしたが、実際にはその方法については述べていませんでした。ヘルプ?

4

1 に答える 1

1

これらは実際のメモリリークではない可能性があります。呼び出す_CrtDumpMemoryLeaks()と、ヒープを通過して解放されていないオブジェクトを探し、それらをリークとして表示します。アプリケーションが終了する前に呼び出しているため、ヒープに割り当てられているものはすべてリークとして表示されます。

wxWidgetsがいくつかのグローバルオブジェクトを作成すると確信しています(たとえば、wxEmptyString、wxDefaultPositionなどがあり、実際にいくつかの割り当てを実行するものがあると思います)。これらはアプリケーションの終了後まで破棄されません。 。_CrtDumpMemoryLeaks()誤検知を表示しないようにするには、その時点以降に呼び出す必要があります。

MSDNで説明されているように_CrtDumpMemoryLeaks()、プログラムの終了時にCRTが自動的に呼び出すようにすることができます。

あなたを助けるかもしれない関連する質問もここにあります。

編集:App :: OnInit()メソッドの先頭に次のコードを追加してこれを自分で試しましたが、表示されるリークは64バイトのものだけで、これは強制リークと一致します。したがって、すべてのwxアプリケーションがリークしているようには見えません。しかし、私もあなたのコードでそれを試しました、そして私はリークが報告されます。

_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );

int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpDbgFlag);

// Force a leak
malloc(64);

App編集2: wxWidgetsがAppクラスをアプリケーションオブジェクトとして使用する(そして独自のWinMainを提供する)ように、クラス定義の後に次の行を含める必要があります。wxAppで実行する場合は、それ自体を適切にクリーンアップするために次の行が必要になると思います。

IMPLEMENT_APP(App)

_CrtSetDbgFlag()編集3:リンクしたwxWidgetsページで、スタートアップコードがデバッグモードで自動的に呼び出すこともわかりました。したがって、コードを自分で追加しなくても、リークを検出できます。これをテストするには、メモリを割り当てて解放しないでください。

于 2012-07-06T08:57:45.807 に答える