How to safely release the memory when I dynamic create the the dialog ?
-
I try this way ,but feel it doesn't safety.
#include "TestDlg.h"
class CMainDlg : CDialog
{
public:
CTestDlg *m_pTestDlg;
void ShowDlg();
void FreeDlg();
}void CMainDlg::ShowDlg()
{
m_pTestDlg = new CTestDlg();
m_pTestDlg->Create(IDD_TEST_DLG,this);
m_pTestDlg->CenterWindow();
m_pTestDlg->ShowWindow(SW_SHOWNORMAL);
m_pTestDlg->UpdateWindow();
}void CMainDlg::FreeDlg()
{
if( m_pTestDlg != NULL )
{
delete m_pTestDlg;
}
}Is this right ? How to safty free the memory ? Thanks for your reply ! Best Regards !
-
I try this way ,but feel it doesn't safety.
#include "TestDlg.h"
class CMainDlg : CDialog
{
public:
CTestDlg *m_pTestDlg;
void ShowDlg();
void FreeDlg();
}void CMainDlg::ShowDlg()
{
m_pTestDlg = new CTestDlg();
m_pTestDlg->Create(IDD_TEST_DLG,this);
m_pTestDlg->CenterWindow();
m_pTestDlg->ShowWindow(SW_SHOWNORMAL);
m_pTestDlg->UpdateWindow();
}void CMainDlg::FreeDlg()
{
if( m_pTestDlg != NULL )
{
delete m_pTestDlg;
}
}Is this right ? How to safty free the memory ? Thanks for your reply ! Best Regards !
You could try the following :) :
void CMainDlg::FreeDlg()
{
if (m_pTestDlg) {
if (m_pTestDlg->GetSafeHwnd()) {
m_pTestDialog->EndDialog(IDCANCEL);
}
delete m_pTestDlg;
m_pTestDlg = NULL; // the same line should be placed in the main dialog constructor
}
}void CMainDlg::OnDestroy()
{
FreeDlg(); // an extra check :)
}virtual void BeHappy() = 0;
-
I try this way ,but feel it doesn't safety.
#include "TestDlg.h"
class CMainDlg : CDialog
{
public:
CTestDlg *m_pTestDlg;
void ShowDlg();
void FreeDlg();
}void CMainDlg::ShowDlg()
{
m_pTestDlg = new CTestDlg();
m_pTestDlg->Create(IDD_TEST_DLG,this);
m_pTestDlg->CenterWindow();
m_pTestDlg->ShowWindow(SW_SHOWNORMAL);
m_pTestDlg->UpdateWindow();
}void CMainDlg::FreeDlg()
{
if( m_pTestDlg != NULL )
{
delete m_pTestDlg;
}
}Is this right ? How to safty free the memory ? Thanks for your reply ! Best Regards !
Another point is that there is no point in having a pointer for your dialog if you at any point are worried about memory. You could just use
CTestDlg m_testDlg;
Using a pointer as you have has only one advantage. You can use a forward declaration of CTestDlg in your header file to avoid compile time dependencies. This will reduce compilation time if you later make changes to CTestDlg. In practice, this applies to large project only. Also, the UpdateWindow() call is superfluous. -
I try this way ,but feel it doesn't safety.
#include "TestDlg.h"
class CMainDlg : CDialog
{
public:
CTestDlg *m_pTestDlg;
void ShowDlg();
void FreeDlg();
}void CMainDlg::ShowDlg()
{
m_pTestDlg = new CTestDlg();
m_pTestDlg->Create(IDD_TEST_DLG,this);
m_pTestDlg->CenterWindow();
m_pTestDlg->ShowWindow(SW_SHOWNORMAL);
m_pTestDlg->UpdateWindow();
}void CMainDlg::FreeDlg()
{
if( m_pTestDlg != NULL )
{
delete m_pTestDlg;
}
}Is this right ? How to safty free the memory ? Thanks for your reply ! Best Regards !
A quick point... IF you're creating a modeless dialogue box (created with Create) then make sure you kill it off using DestroyWindow, not EndDialog. IF you do and you're sure that CTestDlg is only going to be created dynamically then overide PostNCDestroy to clean up the C++ object. It's a bit disgusting but there are so many MFC classes that do it you might as well join in the fun! The advantage is that all you have to do is destroy the window and it'll clean up after itself:
void CTestDialog::PostNCDestroy()
{
delete this;
}Cheers, Ash
-
Another point is that there is no point in having a pointer for your dialog if you at any point are worried about memory. You could just use
CTestDlg m_testDlg;
Using a pointer as you have has only one advantage. You can use a forward declaration of CTestDlg in your header file to avoid compile time dependencies. This will reduce compilation time if you later make changes to CTestDlg. In practice, this applies to large project only. Also, the UpdateWindow() call is superfluous.Normally I'd agree about using a member rather than a dynamically created object. However in the case of a modeless dialogue box you can have the problem of resetting the members of the dialogue (if the dialogue box is closed and reopened) which can lead to some funky fiddling with manually calling destructors and placement new. As soon as you start thinking about that you might as well just say sod it and recreate the object as you need to use it. Cheers, Ash Edited as I said completely the wrong thing and confused Niklas. Sorry!
modified on Thursday, August 19, 2010 7:26 AM
-
Normally I'd agree about using a member rather than a dynamically created object. However in the case of a modeless dialogue box you can have the problem of resetting the members of the dialogue (if the dialogue box is closed and reopened) which can lead to some funky fiddling with manually calling destructors and placement new. As soon as you start thinking about that you might as well just say sod it and recreate the object as you need to use it. Cheers, Ash Edited as I said completely the wrong thing and confused Niklas. Sorry!
modified on Thursday, August 19, 2010 7:26 AM
-
I try this way ,but feel it doesn't safety.
#include "TestDlg.h"
class CMainDlg : CDialog
{
public:
CTestDlg *m_pTestDlg;
void ShowDlg();
void FreeDlg();
}void CMainDlg::ShowDlg()
{
m_pTestDlg = new CTestDlg();
m_pTestDlg->Create(IDD_TEST_DLG,this);
m_pTestDlg->CenterWindow();
m_pTestDlg->ShowWindow(SW_SHOWNORMAL);
m_pTestDlg->UpdateWindow();
}void CMainDlg::FreeDlg()
{
if( m_pTestDlg != NULL )
{
delete m_pTestDlg;
}
}Is this right ? How to safty free the memory ? Thanks for your reply ! Best Regards !
-
When having a modal dialog I have never found the use of dynamically allocate the object. I just create it as automatic on the stack in whatever function I need it.
If I had a brain I'd be dangerous. I should really proof read what I write more. There was a finger faux-pas in my response, I should have said "modeless." For a modal dialogue I wholeheartedly agree - you'd be cracked to not stick it on the stack. Cheers, Ash
-
A quick point... IF you're creating a modeless dialogue box (created with Create) then make sure you kill it off using DestroyWindow, not EndDialog. IF you do and you're sure that CTestDlg is only going to be created dynamically then overide PostNCDestroy to clean up the C++ object. It's a bit disgusting but there are so many MFC classes that do it you might as well join in the fun! The advantage is that all you have to do is destroy the window and it'll clean up after itself:
void CTestDialog::PostNCDestroy()
{
delete this;
}Cheers, Ash
The statement "delete this" is amusing. I always add the comment "// hari kari". Anyway, common practice is to keep a pointer to the modeless dialog in the object that creates it so you can just bring it forward if it is reinvoked ie., the pointer is not null. What I do in this case is I pass the address of that pointer to the dialog object so it can null it when it is closed - usually preceding the "delete this" statement. The PostNCDestroy method then looks like this :
void CTestDialog::PostNCDestroy()
{
if( m_pSelf )
*m_pSelf = NULL; // null parent's pointer to us
delete this;
}That is the best and easiest way I have come up with to deal with the issue so far.