【问题标题】:Is this a memory leak in MFC这是 MFC 中的内存泄漏吗
【发布时间】:2010-10-30 22:49:36
【问题描述】:
// CMyDialog inherits from CDialog 
void CMyFrame::OnBnClickedCreate()
{
    CMyDialog* dlg = new CMyDialog();
    dlg->Create( IDD_MYDIALOG, m_thisFrame );
    dlg->ShowWindow( SW_SHOW );
}

我很确定这会泄漏。我真正要问的是:MFC 中是否有任何“魔法”可以在对话框被销毁时进行对话框清理。如果 dlg 不是指针而是在堆栈上声明,它将如何工作 - 当 dlg 超出范围时,析构函数不会破坏窗口。

【问题讨论】:

    标签: c++ mfc memory-leaks


    【解决方案1】:

    是的,在您的情况下是内存泄漏,但您可以通过使用覆盖 PostNcDestroy 在堆上分配无模式对话框的情况下避免内存泄漏。

    对话框不是为自动清理而设计的(主框架窗口和视图窗口都是)。 如果您想为对话框提供自动清理,那么您必须覆盖派生类中的PostNcDestroy 成员函数。要将自动清理添加到您的类,请调用您的基类,然后执行delete this。要从您的类中删除自动清理,请直接调用 CWnd::PostNcDestroy 而不是直接基类中的 PostNcDestroy 成员。

    void MyDialog::PostNcDestroy() 
    {
    
        CDialog::PostNcDestroy();
        delete this;
    }
    

    这是如何工作的(来自 MSDN):

    销毁 Windows 窗口时, 最后一条 Windows 消息发送到 窗口是 WM_NCDESTROY。默认 该消息的 CWnd 处理程序 (CWnd::OnNcDestroy) 将分离 来自 C++ 对象的 HWND 并调用 虚函数 PostNcDestroy。一些 类将这个函数重写为 删除 C++ 对象。

    "delete this" 将释放任何 C++ 与 C++ 对象关联的内存。 即使默认的 CWnd 析构函数调用 DestroyWindow 如果 m_hWnd 是非 NULL,这不会导致 自句柄以来无限递归 期间将被分离并为 NULL 清理阶段。

    您也可以参考 MSDN (Destroying Window Objects) 了解更多详情。

    注意:

    这适用于可以在上分配的无模式对话框。

    【讨论】:

      【解决方案2】:

      是的,这是一个泄漏。是的,如果对象是堆栈分配的,则窗口将被销毁。使用对话框作为堆栈分配的对象是模态对话框的典型特征 - 您调用一个将对话框显示为模态窗口的方法,并且该方法仅在对话框关闭并且对象随后被销毁时返回。

      【讨论】:

      • 谢谢。我忘了说这是一个无模式对话框。我假设在这种情况下清理对话框对象必须是一个成员变量 - 所以它可以在框架析构函数中被销毁/取消分配。
      【解决方案3】:

      如果您在对话框中手动调用 Create,您也必须手动调用 Destroy
      当使用 DoModal() 时,这不是必需的。

      来自MSDN

      使用 CWnd::DestroyWindow 函数 销毁由 创建函数。

      【讨论】:

        猜你喜欢
        • 2011-02-20
        • 2013-08-12
        • 2013-01-08
        • 2013-11-12
        • 2015-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多