2012-07-05 69 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