这是MFC中的内存泄漏

时间:2009-06-03 10:25:49

标签: c++ mfc memory-leaks

// CMyDialog inherits from CDialog 
void CMyFrame::OnBnClickedCreate()
{
    CMyDialog* dlg = new CMyDialog();
    dlg->Create( IDD_MYDIALOG, m_thisFrame );
    dlg->ShowWindow( SW_SHOW );
}

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

3 个答案:

答案 0 :(得分:16)

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

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

void MyDialog::PostNcDestroy() 
{

    CDialog::PostNcDestroy();
    delete this;
}

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

  

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

     

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

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

注意:

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

答案 1 :(得分:4)

是的,那是泄密。是的,如果对象是堆栈分配的话,窗口将被销毁。使用对话框作为堆栈分配的对象是模态对话框的典型对象 - 您可以调用一个方法将对话框显示为模式窗口,该方法仅在对话框关闭且对象在此之后被销毁时返回。

答案 2 :(得分:3)

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

来自MSDN

  

使用CWnd :: DestroyWindow函数   销毁由...创建的对话框   创建功能。