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

Я уверен, что это утечка. Я действительно спрашиваю: есть ли в MFC «магия», которая выполняет очистку диалогового окна при уничтожении диалога. Как это работает, если dlg не был указателем, а объявлен в стеке - не разрушил бы деструктор окна, когда dlg выходит за рамки.Это утечка памяти в MFC

ответ

12

Да, это утечка памяти в вашем случае, но вы можете избежать утечки памяти в тех случаях, когда немодальный диалог, выделенных в куче, используя переопределение PostNcDestroy.

Диалоги не предназначены для автоматической очистки (где в качестве окон основной рамы, окна вида). Если вы хотите предоставить автоматическую очистку для диалоговых окон, вы должны переопределить функцию-член в производном классе. Чтобы добавить автоматическую очистку в свой класс, вызовите базовый класс, а затем выполните команду delete this. Чтобы удалить автоматическую очистку из вашего класса, вызовите CWnd::PostNcDestroy непосредственно вместо члена PostNcDestroy в вашем прямом базовом классе.

void MyDialog::PostNcDestroy() 
{ 

    CDialog::PostNcDestroy(); 
    delete this; 
} 

Как это работает (из MSDN):

При уничтожении окна окна, Последнего сообщения Windows, отправляется в окно WM_NCDESTROY. По умолчанию Обработчик CWnd для этого сообщения (CWnd :: OnNcDestroy) отсоединяет HWND от объекта C++ и вызывает виртуальную функцию PostNcDestroy. Некоторые классы переопределяют эту функцию до , удаляя объект C++.

«delete this» освободит любую C++ память, связанную с объектом C++. Даже если по умолчанию CWnd деструкторов вызовы в DestroyWindow если m_hWnd не является NULL, это не приводит к бесконечной рекурсии, так как ручка будет обособленным и NULL во время фазы очистки.

Дополнительную информацию можно найти в MSDN (Destroying Window Objects).

Примечание:

Это работает для безрежимного диалога, которые могут быть выделены на кучного.

3

Да, это утечка. И да, окно будет уничтожено, если объект был выделен стекми. Использование диалогов в качестве объектов, связанных с стекем, типично для модальных диалогов - вы вызываете метод отображения диалога в виде модального окна, и этот метод возвращается только после закрытия диалога и уничтожения объекта после этого.

+0

Спасибо. Я забыл сказать, что это для диалога Modeless. В этом случае я предполагаю, что для очистки объект диалога должен быть переменной-членом, поэтому он может быть уничтожен/де-распределен в деструкторе кадров. – Richard

2

Если вручную вызвать Create в диалоге, вы должны вручную Destroy это также.
При использовании DoModal() не нужно.

От MSDN:

Используйте CWnd :: Функция DestroyWindow уничтожить диалоговое окно, созданное Создать функцию.