wxMemoryBuffer object return 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.
User avatar
Death Knight
Experienced Solver
Experienced Solver
Posts: 90
Joined: Mon Feb 28, 2005 10:24 pm
Location: Turkey, Istanbul

wxMemoryBuffer object return

Post by Death Knight »

Hi all.

I am curious about that why this is illegal. I want to return prepared wxMemoryBuffer object.

Code: Select all

void OnCmd(wxCommandEvent& event){
	char *bfr = static_cast<char*>(GetBin().GetData());
	printf( "wxMemoryBuffer after  return : 0x%02X \n", *bfr);
	}

wxMemoryBuffer GetBin(){
	wxMemoryBuffer memodata;
	char bfr = 0x31;
	memodata.AppendByte( bfr );
	char *bfrx = static_cast<char*>(memodata.GetData());
	printf( "wxMemoryBuffer before return : 0x%02X \n", *bfrx);
	return memodata;
	}
I got output of

Code: Select all

wxMemoryBuffer before return : 0x31 
wxMemoryBuffer after  return : 0x60
Vladz said that
You use a pointer inside the already destroyed wxMemoryBuffer object in OnCmd(), this is a bug in your code.
I understand that local `memodata` in GetBin() function is destroyed after return, but I am not returning pointer or reference of memodata, I am returning whole object. I thought wxMemoryBuffer will copied to Cmd() function, so GetData() needs work. But it isn't. Whats the point I miss :?:
User avatar
doublemax
Moderator
Moderator
Posts: 19164
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Post by doublemax »

Code: Select all

void OnCmd(wxCommandEvent& event){
  char *bfr = static_cast<char*>(GetBin().GetData());
  // at this point the object returned by GetBin() is already destroyed
  // so the pointer you previously got from GetData() is invalid now
  printf( "wxMemoryBuffer after  return : 0x%02X \n", *bfr);
}
Use the source, Luke!
TrV
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 630
Joined: Wed Jul 04, 2007 1:12 pm

Post by TrV »

Maybe is GetData() destructive ? Like a stack's pop() ?
User avatar
Death Knight
Experienced Solver
Experienced Solver
Posts: 90
Joined: Mon Feb 28, 2005 10:24 pm
Location: Turkey, Istanbul

Post by Death Knight »

Okey, I already understand that. But I am questioning that where is the copy of that object? I am returning copy of that object right? I am not defined GetBin() as

Code: Select all

wxMemoryBuffer* GetBin() //or
wxMemoryBuffer& GetBin() //with this I understand that returning object will destroyed.

Code: Select all

void OnCmd(wxCommandEvent& event){
        wxMemoryBuffer z = GetBin();
        // at this point I understand that the LOCAL object of GetBin is already destroyed.
        //But why returning object is destroyed too? I return copy of it, didn't I?
        //If I return that object as a pointer or reference yes I can understand this situation.
        }
wxMemoryBuffer GetBin(){
        wxMemoryBuffer memodata;
        char bfr = 0x31;
        memodata.AppendByte( bfr );
        return memodata;
        }
Returning wxMemoryBuffer object is illegal? If its illegal, needed to indicate in Documentation.
jfouche
Super wx Problem Solver
Super wx Problem Solver
Posts: 442
Joined: Tue May 06, 2008 4:52 pm
Location: France

Post by jfouche »

When you do :

Code: Select all

char *bfr = static_cast<char*>(GetBin().GetData());
the bfr var point on invalid datas, because you return a copy that is destroy at the end of the line. As you don't copy it, it is lost. The compiler think you don't need it anymore at the end of the call of GetBin().GetData(). What happen is that calling GetBin() put the wxMemoryBuffer copy on the stack, then call GetData() on it, then destroy it.

If you do :

Code: Select all

wxMemoryBuffer z = GetBin();
You got an explicit copy of the buffer in your z var. As it is a copy, it doesn't point on the same buffer as the original one, but you can use it without problem (the data containing in the buffer is the same content, not the same address).

Now, you can use the data without problem :

Code: Select all

char *bfr = static_cast<char*>(z.GetData());
You just have to remember that the bfr pointer is valid until the next bracket, which will destroy the memory buffer.

Is it more clear ?
Jérémie
User avatar
Death Knight
Experienced Solver
Experienced Solver
Posts: 90
Joined: Mon Feb 28, 2005 10:24 pm
Location: Turkey, Istanbul

Post by Death Knight »

Yes It's more clear now. I am thinking blind this days. Even tried z = GetBin(), complex code returns false comments. Thank you for this.