deleting a function pointer doesn't work since wx-2.9.3 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
schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Sat Mar 03, 2012 8:29 pm

Hi all,

I changed from wxWidget-2.9.2 to wxWidgets-2.9.3 and now deleting a function pointer doesn't work.
I'm using wxMSW on WinXP. The compiler is MingW with gcc-4.4.0.

Now my Project:

the exe file is a kind of framework. The functionality is done inside dll's.
Inside the ai_nnet_mlp_gui.dll I'm calling another dll to show a plot. I'm doing this
with function pointers. If I'm clicking on the close-cross on the right top side, the vis_basic_2D-frame
is closing and calls a function which deletes the pointer in the ai_nnet_mlp_gui.dll!

exe -----> ai_nnet_mlp_gui.dll ----> vis_basic_2d.dll
|______________________|

The code in the "onClose" function is:

Code: Select all

void VisBasic2DFrame::onClose(wxCloseEvent& event)
{
	Destroy();


	if (pMemFuncResetShowPlot_){
		pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_);

		pMemFuncResetShowPlot_ = NULL;
		pt2ObjectResetShowPlot_ = NULL;
	}

	if (pFuncShowPlot_){
		pFuncShowPlot_ = NULL;
	}

	if (pt2Object_){
		pt2Object_ = NULL;
	}

	if (pMemFuncShowPlot_){
		pMemFuncShowPlot_ = NULL;
	}

}//void VisBasic2DFrame::onClose(...
This is working very vell with wxWidgets-2.9.2, but with wxWidgets-2.9.3
the line

Code: Select all

pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_);
crashs the application. I have no idea why ...

I hope somebody can help me

Thanks
Michael

Muetdhiver
Super wx Problem Solver
Super wx Problem Solver
Posts: 323
Joined: Sun Jun 08, 2008 11:59 am
Location: Bordeaux, France

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by Muetdhiver » Sun Mar 04, 2012 9:55 am

Wow,

it seems more a memory problem than a wxWidgets one.

Maybe something have a side effect one your code, there are memory leaks somewhere, and changing to wx2.9.3 shows up the error.
Are you using your framework in debug mode ? in release ?

Maybe there is something wrong in your code and changing memory space with a new wxWidgets version has broken your dll.

Sorry, I can't help more, but the only thing you have to do is to try segregating your code (removing some parts) to find where the problem comes, and extract a minimal sample that crashes.
Otherwise, in is not possible to deduce something.

And again : it is probably not due to wxWidgets !

Bye.
OS: Ubuntu 11.10
Compiler: g++ 4.6.1 (Eclipse CDT Indigo)
wxWidgets: 2.9.3

schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Mon Mar 05, 2012 7:30 pm

Hi Muetdhiver,

thanks for your answers. It's of course not what I was hopping for :-)
Do you know some usefull tools to search memory leaks inside
a dll? I couldn't found some open-source or freeware ...
which I can use on windows.

Thanks again

Michael

Auria
Site Admin
Site Admin
Posts: 6695
Joined: Thu Sep 28, 2006 12:23 am
Contact:

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by Auria » Wed Mar 07, 2012 12:44 am

I don't think leaks are to blame.
I would start by checking if "pt2ObjectResetShowPlot_" is a valid pointer (if a pointer?), if it's dangling or something like that it may explain a crash
"Keyboard not detected. Press F1 to continue"
-- Windows

schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Fri Mar 09, 2012 9:02 pm

Hi

thanks for the hints.
I compiled the libraries once more with the settings

#define wxUSE_DEBUG_CONTEXT 1
#define wxUSE_MEMORY_TRACING 1

and now each newly compiled library can't be loaded.
So I think I do it again with

#define wxUSE_DEBUG_CONTEXT 1
#define wxUSE_MEMORY_TRACING 0

and will see if I get some help from the debug_context ...

Michael

schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Fri Apr 06, 2012 9:32 pm

Hi all

I still couldn't find a solution to my problem, so I will describe the problem more detailed.

wxVersion: 2-9-3, wxmsw
compiler: mingw gcc 4.4.0

Now let me explain with some code. Below you can see a part of a function which decide if the plot (which causes the crash when it will be closed) is
used or not! I inserted some logging functions and at this position, it's something strange, but I'm not sure if I'm doing everything right!
The function call:
mlp_->setMemFuncPointShowPlot((void*) this, &NnetGUIBase::Wrapper_To_Call_showPerfPlot);
uses function pointers. So for the logging, I tried to determine the address of the pointers.
Can I do it on this way for the "this" pointer?
I get the same address as for the
)&NnetGUIBase::Wrapper_To_Call_showPerfPlot;
function pointer! See the
part from the logging after the code snippet!

Code: Select all

if (this->enablePerfPlot_->GetValue()){
			//
			// now define the function pointer to pass
			// to the ai::nnet::mlp library.
			// The first argument '(void*) this'
			//
			Logging *loger = new Logging();

			int adr = (int)(void*)this;
			char buf[33];
			itoa(adr, buf, 10);
			loger->log("the address of the this pointer is:");
			loger->log(buf);

			int adr2 = (int)&NnetGUIBase::Wrapper_To_Call_showPerfPlot;
			char buf2[33];
			itoa(adr2, buf2, 10);
			loger->log("the address of the NnetGUIBase::Wrapper_To_Call_showPerfPlot pointer is:");
			loger->log(buf);

			mlp_->setMemFuncPointShowPlot((void*) this, &NnetGUIBase::Wrapper_To_Call_showPerfPlot);

			delete loger;
		}else
Fri Apr 06 22:54:05 2012 : File: ..\src\nnetGUIBase.cpp: Function: onTrainButton --Line: 1887: the address of the this pointer is:
Fri Apr 06 22:54:05 2012 : File: ..\src\nnetGUIBase.cpp: Function: onTrainButton --Line: 1888: 61051472
Fri Apr 06 22:54:05 2012 : File: ..\src\nnetGUIBase.cpp: Function: onTrainButton --Line: 1893: the address of the NnetGUIBase::Wrapper_To_Call_showPerfPlot pointer is:
Fri Apr 06 22:54:05 2012 : File: ..\src\nnetGUIBase.cpp: Function: onTrainButton --Line: 1894: 61051472
Inside the mlp_ object the function pointer is called and on this way I call the next function

Code: Select all

/*!
 * Static wrapper-function to be able to callback the member function showProgPlot
 */
void NnetGUIBase::Wrapper_To_Call_showPerfPlot(void* pt2Object, stl_dVector perf, stl_dVector valiPerf)
{
	//
    // Explicitly cast to a pointer to NnetGUIBase
	//
	NnetGUIBase* mySelf = (NnetGUIBase*) pt2Object;

	//
    // Call member
	//
    mySelf->showProgPlot(perf, valiPerf);

}//void NnetGUIBase::Wrapper_To_Call_showPerfPlot...

Code: Select all

void NnetGUIBase::showProgPlot(stl_dVector perf, stl_dVector valiPerf)
{

	Logging *loger = new Logging();

	int adr = (int)&visBasic2D_;
	char buf[33];
	itoa(adr, buf, 10);
	loger->log("the address of the visBasic2D_ pointer is:");
	loger->log(buf);

	if (!visBasic2D_){ // object exists, check if library is loaded

		if (libVisBasic2D_.IsLoaded()){ // returns true if library is loaded

			std::cout << "already loaded vis_basic_2D.dll\n";

			getVisBasic2DDllObj pGetDllObj = (getVisBasic2DDllObj)libVisBasic2D_.GetSymbol("createVisBasic2D");
			visBasic2D_ = (pGetDllObj)();

			visBasic2D_->setMemFuncPointResetShowPlot((void*) this, NnetGUIBase::Wrapper_To_Reset_showPlot);

		}else{ // load the library

			if (libVisBasic2D_.Load("./plugins/vis_basic_2D")){
				std::cout << "load vis_basic_2D.dll successfully\n";

				getVisBasic2DDllObj pGetDllObj = (getVisBasic2DDllObj)libVisBasic2D_.GetSymbol("createVisBasic2D");
				visBasic2D_ = (pGetDllObj)();
				visBasic2D_->setMemFuncPointResetShowPlot((void*) this, NnetGUIBase::Wrapper_To_Reset_showPlot);

			}else{
				///todo throw an exception
				loger_->log("Couldn't load the library: vis::basic::2D");
				std::cout << "Couldn't load the library: vis::basic::2D\n";
			}

		}
	}else{ // in this case the object should be valid


	}// if (!visBasic2D_...


	if (visBasic2D_){

		if (visBasic2D_->isShown()){
			// do nothing
		//	std::cout << "short before performancePlot\n";
			visBasic2D_->performancePlot(perf,valiPerf);
		}else{
			visBasic2D_->show();
		}

	}else{
		std::cout << "visBasic2D_ seems not to be valid\n";

	}// if (visBasic2D_)

delete loger;
}//void NnetGUIBase::showProgPlot(...
Until this position, everything seems to be okay. But if I close now the plot frame, I get the crash, even if it looks to me
that the pointer of the visBasic2D_ object is still the same!

Code: Select all

/*!
 * Static wrapper-function to be able to callback the member function resetShowPlot
 */
void NnetGUIBase::Wrapper_To_Reset_showPlot(void* pt2Object)
{
	Logging *loger = new Logging();
    // explicitly cast to a pointer to NnetGUIBase
	NnetGUIBase* mySelf = (NnetGUIBase*) pt2Object;

	loger->log("before the resetShowPlot command");
    // call member
    mySelf->resetShowPlot();

    delete loger;
}//void NnetGUIBase::Wrapper_To_Reset_showPlot(void* pt2Object)

Code: Select all

/*!
 * Sets the function pointer visBasic2D_ to NULL. This function is used
 * inside the Wrapper-Functions to pass data to and from the ai::nne::mlp
 * library.
 */
void NnetGUIBase::resetShowPlot()
{
	Logging *loger = new Logging();

	int adr = (int)&visBasic2D_;
	char buf[33];
	itoa(adr, buf, 10);
	loger->log("the address of the visBasic2D_ pointer is:");
	loger->log(buf);

	delete visBasic2D_;  // muss noch getestet werden !!

	loger->log("after delete visBasic2D_");
	visBasic2D_ = NULL;
	loger->log("after visBasic2D_=NULL");

	delete loger;

}//void NnetGUIBase::resetShowPlot()
As everyone can see, the logging part of the visBasic2D_ seems to be ok.
Fri Apr 06 22:54:05 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:05 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3118: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:06 2012 : File: ..\src\nnetGUIBase.cpp: Function: showProgPlot --Line: 3119: 61052036
Fri Apr 06 22:54:07 2012 : File: ..\src\nnetGUIBase.cpp: Function: Wrapper_To_Reset_showPlot --Line: 3230: before the resetShowPlot command
Fri Apr 06 22:54:07 2012 : File: ..\src\nnetGUIBase.cpp: Function: resetShowPlot --Line: 2721: the address of the visBasic2D_ pointer is:
Fri Apr 06 22:54:07 2012 : File: ..\src\nnetGUIBase.cpp: Function: resetShowPlot --Line: 2722: 61052036
Fri Apr 06 22:54:07 2012 : File: ..\src\nnetGUIBase.cpp: Function: resetShowPlot --Line: 2726: after delete visBasic2D_
Fri Apr 06 22:54:07 2012 : File: ..\src\nnetGUIBase.cpp: Function: resetShowPlot --Line: 2728: after visBasic2D_=NULL
At the end, let me show you that the function pointers are correct for reseting the plot frame ...
Fri Apr 06 23:28:47 2012 : File: ..\src\visBasic2D_frame.cpp: Function: setMemFuncPointResetShowPlot --Line: 318: the address of the pointer pt2ObjectResetShowPlot_ is:
Fri Apr 06 23:28:47 2012 : File: ..\src\visBasic2D_frame.cpp: Function: setMemFuncPointResetShowPlot --Line: 319: 61190096
Fri Apr 06 23:28:47 2012 : File: ..\src\visBasic2D_frame.cpp: Function: setMemFuncPointResetShowPlot --Line: 326: the address of the function pointer pMemFuncResetShowPlot_ is:
Fri Apr 06 23:28:47 2012 : File: ..\src\visBasic2D_frame.cpp: Function: setMemFuncPointResetShowPlot --Line: 327: 61190104
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 203: after Destroy
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 207: inside if (pMemFuncResetShowPlot_
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 208: inside if (pt2ObjectResetShowPlot_
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 210: after pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_)
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 216: the address of the pointer is:
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 217: 61190096
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 222: the address of the function pointer is:
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 223: 61190104
Fri Apr 06 23:28:49 2012 : File: ..\src\visBasic2D_frame.cpp: Function: onClose --Line: 228: END OF void VisBasic2DFrame::onClose(...
Does anyone have some more hints?

Thanks for any help

Michael

User avatar
doublemax
Moderator
Moderator
Posts: 15277
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by doublemax » Sat Apr 07, 2012 8:47 am

I get the same address as for the [...] function pointer!
That's probably because you're outputting "buf" twice instead of using "buf2" the second time.

In general i'm a little confused about the title. In 99% of all cases you don't delete a function pointer. I'm not sure if that's what you're doing or if it's just a matter of bad wording.

BTW, this is too complicated:

Code: Select all

int adr = (int)(void*)this;
char buf[33];
itoa(adr, buf, 10);
loger->log("the address of the this pointer is:");
loger->log(buf);

Code: Select all

wxLogDebug("the address of the this pointer is %p", this);
// or
loger->log( wxString::Format("the address of the this pointer is %p", this) );
Where exactly does it crash? Can't you use a debugger? What about a backtrace?
Use the source, Luke!

schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Mon Apr 09, 2012 6:40 pm

Hi doublemax

You're right of course, I don't try to delete a function pointer!
The crash occures at the line pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_);
and as you can see, I tried to create a memory dump which doesn't work. I coulnd't figure out why.

Code: Select all

void VisBasic2DFrame::onClose(wxCloseEvent& event)
{

	Logging *loger = new Logging();


//	FILE * pFile;
//	pFile = fopen( "log.log", "w" );
//
//
//	wxDebugContext::SetCheckpoint(false);
//
//	wxLog* oldLog = wxLog::SetActiveTarget(new wxLogStderr(pFile));



//	if (pFuncShowPlot_){
		pFuncShowPlot_ = NULL;
//	}

//	if (pt2Object_){

		pt2Object_ = NULL;
//	}

//	if (pMemFuncShowPlot_){
		pMemFuncShowPlot_ = NULL;
//	}

	Destroy();
	loger->log("after Destroy");
	// muss ev. gleich wieder auskommentiert werden 03.04.2012
	if (pMemFuncResetShowPlot_){
		if (pt2ObjectResetShowPlot_)
			loger->log("inside if (pMemFuncResetShowPlot_");
			loger->log("inside if (pt2ObjectResetShowPlot_");
			pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_);
			loger->log("after pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_)");
	}

	int adr = (int)&pt2ObjectResetShowPlot_;
	char buf[33];
	itoa(adr, buf, 10);
	loger->log("the address of the pointer is:");
	loger->log(buf);

	int adr2 = (int)&pMemFuncResetShowPlot_;
	char buf2[33];
	itoa(adr2, buf2, 10);
	loger->log("the address of the function pointer is:");
	loger->log(buf2);

	pMemFuncResetShowPlot_ = NULL;
	pt2ObjectResetShowPlot_ = NULL;

	loger->log("END OF void VisBasic2DFrame::onClose(...");
//	wxDebugContext::PrintClasses();
//	wxDebugContext::Dump();
//	wxDebugContext::PrintStatistics();
//
//	delete wxLog::SetActiveTarget(oldLog);
//
//	fclose(pFile);
	delete loger;

}//void VisBasic2DFrame::onClose(...
Thanks for your hint with using twice the "buf" :oops: .

Using a debuger seems to be a problem. I'm using the mingw compiler and the dbg debuger with eclipse!
Eclipse seems to be the problem :-(
The crash occures inside a dll ....
Each time I try to use the debuger, I get the error message
No source availabble for "ntdll!DebUiConnectToDbg() at 0x7c91120f"
that's one of my biggest problems.

Thanks for your help.

Michael

User avatar
doublemax
Moderator
Moderator
Posts: 15277
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by doublemax » Mon Apr 09, 2012 7:03 pm

Code: Select all

pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_);
If this line crashes there are not many possible causes. Either the function pointer is bad (this can easily be checked by just printing its address as you did), or the memory it points to is cleared already/corrupted.

If you can't debug it "normally", try logging the first few bytes at the function pointer.

Also, i'm not sure if it's relevant here, but it's definitely not good: The Destroy() call should be at the end of the method, maybe you're cutting the branch you're sitting on.
Use the source, Luke!

schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Tue Apr 10, 2012 7:47 pm

Hi doublemax,

I updated my mingw and dbg and also eclipse/cdt to version 8.0.2.
On a vista pc, I can debug again, but not on a xp pc!

But I think you got it, I cut my branch ( I think so at this moment).

with the line

Code: Select all

pMemFuncResetShowPlot_(pt2ObjectResetShowPlot_);
I delete the object pointer of the plot frame with the function pointer, but I think the
plot object self isn't realy deleted.

I will try some things, but need some more time.
I will write as soon as I could test my code ideas.

Thanks
Michael

schmmichael
Experienced Solver
Experienced Solver
Posts: 96
Joined: Fri Jan 19, 2007 10:38 am
Location: Switzerland

Re: deleting a function pointer doesn't work since wx-2.9.3

Post by schmmichael » Thu Apr 12, 2012 10:35 am

hi doublemax,

you got it!
I cut my own branch im sitting on :-(

I try to explain:

1. I have a GUI object: ai_nnet_mlp_gui
2. Inside this GUI object, I created the visBasic2D object.
3. Inside the visBasic2D object, I used the function pointer from the ai_nnet_mlp_gui object, to delete the visBasic2D object in the onClose method.

So I deleted the visBasic2D object to early and the destructor couldn't make its work :-(

Thanks for your discussion and help.

Michael

Post Reply