我正在尝试制作一个基本的wxWidgets程序,它不会泄漏任何内存(我正在开发Windows 7并使用Visual Studio 2010并尝试使用CRT来检查泄漏)。
我从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类不会在任何地方使用。类外的函数定义是必要的,以防止它被优化掉。如果类App 不,则不会发生错误。
问题是,为什么这不起作用?如何制作无泄漏的wxWidgets程序?我应该如何使用_CrtDumpMemoryLeaks()?为什么没有这方面的资源 - 如果有的话,他们在哪里?我能找到的最好的是this,它只建议使用CRT,但实际上没有说明如何。帮助
答案 0 :(得分: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)。我猜测它在wxApp中的作用需要这一行才能正确清理自己:
IMPLEMENT_APP(App)
编辑3:我还发现,在链接到的wxWidgets页面中,启动代码将在调试模式下自动为您调用_CrtSetDbgFlag()
。因此,您无需自行添加代码即可获得泄漏检测。您可以通过分配一些内存而不是释放它来测试它。