2012-07-05 68 views
1

我試圖做一個基本的wxWidgets程序,不泄漏任何內存(我在Windows 7上開發並且正在使用Visual Studio 2010並嘗試使用CRT來檢查泄漏)。做一個簡單的wxWidgets程序沒有內存泄漏

我從OpenGL示例開始並逐漸處理它。在將CRT調用添加到我的wxApp對象的OnExit方法(只有的地方,我甚至看到它提到過)之後,我意識到內存正在泄漏到處。

我逐漸摸索下來,更直到我創造了這個示例代碼,這使得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是而不是,則不會發生錯誤。

問題是,爲什麼不能正常工作?我如何製作一個無泄露的wxWidgets程序?我應該如何使用_CrtDumpMemoryLeaks()?爲什麼沒有這方面的資源 - 如果有,它們在哪裏?我能找到的最好的是this,它只建議使用CRT,但實際上並沒有說明如何。幫幫我?

回答

1

這些可能不是真正的內存泄漏。當您致電_CrtDumpMemoryLeaks()時,它會遍歷堆尋找尚未釋放的對象並將其顯示爲泄漏。由於您在應用程序結束之前調用它,因此堆中分配的任何內容都將顯示爲泄漏。我很確定wxWidgets創建了一些全局對象(例如,我知道有wxEmptyString,wxDefaultPosition等等,我敢說還有其他人會真正執行一些分配),直到你的應用程序結束。在該點之後需要調用_CrtDumpMemoryLeaks()以便不顯示誤報。

您可以嘗試讓CRT在程序退出as explained on MSDN處自動調用_CrtDumpMemoryLeaks()

還有一個相關的問題here可能會幫助你。

編輯:我已經嘗試過,我自己通過將下面的代碼添加到我的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); 

編輯2:你需要包括你的App類定義後,下面的行,這樣的wxWidgets使用您的App類的應用對象(並提供它自己的WinMain)。我猜whetever它在wxApp需要此線,以自己收拾妥當:

IMPLEMENT_APP(App) 

編輯3:我也發現,在您鏈接到的啓動代碼會自動調用_CrtSetDbgFlag() wxWidgets的頁面爲你在調試模式。所以你不必自己添加代碼即可進行泄漏檢測。你可以通過分配一些內存來測試它,而不是釋放它。

+0

經過多次調整後,我將它整合到以下內容中:http://pastebin.com/EUF6zJ2c。看起來IMPLEMENT_APP不知怎的比我想象的要多。謝謝您的幫助, – imallett 2012-07-11 02:40:12