String corrupts after function return

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
MickeyKnox
Posts: 58
Joined: Tue Apr 10, 2007 7:49 pm
Location: Karlsruhe

String corrupts after function return

Post by MickeyKnox »

I don't know if have a irrlicht problem, or a general C++ problem.
Returning a wchar_t* seems to be corrupt somehow. I made a minimal
example to reproduce the error:

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

const wchar_t* func()
{
  core::stringw Text(L"First line\nSecond line\nThird line");
  //core::stringw Text(L"text");

  core::stringc text(Text.c_str());
  std::cout << text.c_str() << std::endl;

  return Text.c_str();
}

int main()
{
  core::stringc text(func());
  std::cout << text.c_str() << std::endl;
}
The output of this is:

Code: Select all

First line
Second line
Third line
pprst line
Second line
Third line
For Text being just "text" the output is:

Code: Select all

text

I have absolutely no idea, what is going on here.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: String corrupts after function return

Post by randomMesh »

MickeyKnox wrote:

Code: Select all

const wchar_t* func() 
{
   ...
}

int main()
{
  core::stringc text(func());
  std::cout << text.c_str() << std::endl;
}
What happens if you change core::stringc text(func()); to core::stringw text(func()); ?
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

core::stringw Text is created on the stack. The memory that it allocates internally is on the heap, but when func() returns, Text is destroyed, its destructor is called, and its memory freed. You are returning a pointer to freed memory, which is being crapped over before you get a chance to copy the contents.

Code: Select all

const wchar_t* func()
{
  core::stringw Text(L"First line\nSecond line\nThird line");
  // Text now contains that string in memory allocated on the heap.
 
  return Text.c_str();
  // The function will now return a pointer to that heap memory

} // UH OH - Text is destroyed, and its destructor deletes the heap memory.  That makes it fair game to be re-used.
// The pointer to the destroyed memory is returned...

int main()
{
  // ...and here's func(), returning that pointer to the destroyed memory.
  // The contents of that memory could be anything.  You're seeing a couple of characters being crapped over
  // but the entire memory could be gibberish by the time it gets passed into the constructor of text()
  core::stringc text(func());

  std::cout << text.c_str() << std::endl;
} 

I'm not sure what your requirements are, but I'd recommend returning a stringw, either by value or reference.

E.g.

Code: Select all

core::stringw func()
{
  core::stringw Text(L"First line\nSecond line\nThird line");

  core::stringc text(Text.c_str());
  std::cout << text.c_str() << std::endl;

  return Text;
}

int main()
{
  core::stringc text(func().c_str());
  std::cout << text.c_str() << std::endl;
} // Note that the stringw returned from func() will be implicitly destroyed here
or

Code: Select all

void func(core::stringw & outString)
{
  outString = L"First line\nSecond line\nThird line";
 
  core::stringc text(outString.c_str());
  std::cout << text.c_str() << std::endl;
}

int main()
{
  core::stringw wideString;
  func(wideString);
  core::stringc text(wideString.c_str());
  std::cout << text.c_str() << std::endl;
} // Note that wideSrting will be implicitly destroyed here
Last edited by rogerborg on Fri Feb 08, 2008 3:19 pm, edited 1 time in total.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
MickeyKnox
Posts: 58
Joined: Tue Apr 10, 2007 7:49 pm
Location: Karlsruhe

Post by MickeyKnox »

Thanks rogerborg. I just need to make my variable a class variable.
In my minimal example, making Text a global variable would work.
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I'm not sure why you return a wchar_t*, but if you return a strinc it should work:

Code: Select all

const stringc func(){
  core::stringc Text(L"First line\nSecond line\nThird line");

  return Text;
}

int main(){
  core::stringc text = func();
  printf("%s\n", text.c_str());

  return 0;
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
MickeyKnox
Posts: 58
Joined: Tue Apr 10, 2007 7:49 pm
Location: Karlsruhe

Post by MickeyKnox »

Yes, thanks again. I observed, that returning a stringw would work, but i didn't got why. Thanks for your explanations.

I guess i stick with my class variable solution, since i want my GUIElement act like the irrlicht GUIElements, returning const wchar_t*

@randomMesh: a stringw wouldn't work, because i can't pass a wchar_t* to std::cout
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

MickeyKnox wrote:@randomMesh: a stringw wouldn't work, because i can't pass a wchar_t* to std::cout
Yeah. I totally overlooked the heap / stack thing. I really should test my suggestions before posting them. :roll:
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

MickeyKnox wrote:I observed, that returning a stringw would work, but i didn't got why
It's because you don't return a pointer/reference but you then return a copy of the stringc/w... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
pippy
Posts: 49
Joined: Sun Jul 08, 2007 11:31 pm

Post by pippy »

I thought that wide characters needed to be printed out using std::wcout
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

it's stringc printed, not stringw... ;)
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
Post Reply