wxWidgets Destructor Abort Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

wxWidgets Destructor Abort

Post by Natulux »

Hey guys,

today I noticed, that my project does not run through my chain of destructors, when I try to delete a certain frame derived object (manually). It takes several seconds of trying before the app is shut down for good (Tray Icon is not cleared correctly etc.).

I use one routine to end my app, it is called like that:

Code: Select all

wxGetApp().ExitApp();

Code: Select all

void MyApp::ExitApp()
{
	//Same Problem with either wxDELETE or delete
	//wxDELETE(misbehavingClass);
	delete misbehavingClass;

	if (!m_frame->Close(false))
	{
		//testing purpose, can this really happen?
		m_frame->Close(true); //Starting the destruction of all the rest and closing
	}
}
If I don't delete the misbehavingClass (manually), the destructor isn't called and everything is fine (in this case). But I don't understand it.
called destructor:

Code: Select all

MisbehavingClass::~MisbehavingClass()
{
	//those two timers are wxTimer
	delete m_timerNotify; //OK
	delete m_timerSuspend; //OK
	delete mysplash; // <--- Causing problems
	//wxDELETE(mysplash); // <--- Causing problems
}
The problem causing object is wxFrame derived and usually short lived:

Code: Select all

class MySplashFrame : public wxFrame
In this case though, the MySplashFrame might also be called without a timeout and must be closed on shutdown manually!

It is called without a parent (NULL) and is stored in a member variable:

Code: Select all

wxDELETE(mysplash);
mysplash = new MySplashFrame(wxDefaultPosition, wxDefaultSize, sMsgText, NULL, factor, lTimeout);
mysplash->ShowWithoutActivating();
The MySplashFrame class has no manually written destructor, this is handled automatically by vs2015 (essentials). (Or am I wrong here?)

Anything jumping to your Eye?

Thanks.
Natu

[EDIT:]
I also tried to Close instead of delete - this is the better choice if I remember correctly. But the problem still exists:

Code: Select all

//wxDELETE(mysplash);
if (mysplash)
{
	mysplash->Close(true);
}
Last edited by Natulux on Wed Nov 07, 2018 12:45 pm, edited 1 time in total.
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxWidgets Destructor Abort

Post by doublemax »

What happens if you just call wxGetApp().ExitMainLoop() without your own ExitApp() method? This should close all open toplevel windows and terminate gracefully.
Use the source, Luke!
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxWidgets Destructor Abort

Post by PB »

I believe using delete for wxWindows is not recommended: if you do not want to use Close() you should use Destroy() instead, see
https://docs.wxwidgets.org/3.1/classwx_ ... 276f5ef8d7
Last edited by PB on Wed Nov 07, 2018 1:10 pm, edited 1 time in total.
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxWidgets Destructor Abort

Post by Natulux »

doublemax wrote:What happens if you just call wxGetApp().ExitMainLoop() without your own ExitApp() method? This should close all open toplevel windows and terminate gracefully.
Interesting! Im not sure what exactly ExitMainLoop does, but it certainly makes a better job then my deletion and frame closing. I have the feeling, that closing the app takes a little longer now, but it is at least clean and all destructors are called.
I just prepped my Exit-func with

Code: Select all

void MyApp::ExitApp()
{
	ExitMainLoop();
	return;
}

and skipped the rest.

I think, I can go with that, though I still dont understand my error.
Thanks Max!

Best
Natu
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxWidgets Destructor Abort

Post by Natulux »

PB wrote:I believe using delete for wxWindows is not recommended: if you do not want to use Close() you should use Destroy() instead, see
https://docs.wxwidgets.org/3.1/classwx_ ... 276f5ef8d7
Thank you for your input, PB. ;-)

Yes, I thought i remembered that, too.
That is why I edited my main post, when I tried

Code: Select all

if (mysplash)
{
	mysplash->Close(true);
}
instead off deletion.
That might be the better approach, didn't solve the problem though.

Best
Natu
Manolo
Can't get richer than this
Can't get richer than this
Posts: 828
Joined: Mon Apr 30, 2012 11:07 pm

Re: wxWidgets Destructor Abort

Post by Manolo »

Perhaps you suffer some delete issue as explained in the doc: https://docs.wxwidgets.org/trunk/overvi ... p_shutdown
Natulux
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 242
Joined: Thu Aug 03, 2017 12:20 pm

Re: wxWidgets Destructor Abort

Post by Natulux »

Manolo wrote:Perhaps you suffer some delete issue as explained in the doc: https://docs.wxwidgets.org/trunk/overvi ... p_shutdown
In particular, do not destroy them from application class' destructor!
The reason for that is that m_helpCtrl is a member object and is thus destroyed from MyApp destructor. But MyApp object is deleted after wxWidgets structures that wxCHMHelpController depends on were uninitialized! The solution is to destroy HelpCtrl in OnExit:
int MyApp::OnExit()
{
delete m_helpCtrl;
return 0;
}
If this information is still valid, then yes - I tried to destroy my pointer to early - I have not overwritten the OnExit().

One has to get used to this kind of behaviour. It works quite nice if you are lazy and let it all happen automatically - but taking these matters in your own hands is quite error prone.

Thanks Manolo!
Have a great day
Natu
Post Reply