【问题标题】:Make a Simple wxWidgets Program Without Memory Leaks制作一个没有内存泄漏的简单 wxWidgets 程序
【发布时间】:2012-07-05 23:17:53
【问题描述】:

我正在尝试制作一个不会泄漏任何内存的基本 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,但实际上并没有说明如何使用。帮忙?

【问题讨论】:

    标签: memory-leaks wxwidgets


    【解决方案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()。因此,您无需自己添加代码即可进行泄漏检测。您可以通过分配一些内存而不是释放它来测试它。

    【讨论】:

    • 经过多次调整后,我将其合并到以下内容中:pastebin.com/EUF6zJ2c。不知何故,IMPLEMENT_APP 似乎比我想象的要多。感谢您的帮助,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 2013-03-01
    • 2018-12-29
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多