Getting a weird string 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
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Getting a weird string return

Post by LunaRebirth »

I'm going to make this as short as possible, but it's been stressing me out for the last 12 hours.

Basically I'm reading content from a file to run as a lua script.
For each script, there is a new LuaScript() object created.
The jist of what I'm doing is absolutely nothing new, and pretty basic, so I don't understand why I'm having issues.

When I use lua to run LuaScript[x]->getCont() (Runs the content of the lua file), it runs fine with no issues.
But when I do something like a print statement using LuaScript[x]->getCont(), I'm given a piece of the content, with nothing else in the print.

For example,

Code: Select all

printf("This text isn't appearing. This content is cut into a piece: %s\n", script[0]->getCont());
Pretending that content holds "test", the output would be:
"te"
even without the beginning part of the printf statement.

I don't understand what's going on as this is a new issue I have never encountered.
I've change LuaScript's cont variable to be a char* and an std::string with no change in results.

The weird thing is that running the Lua using getCont() uses the entire correct content. But using getCont() to print it does not work.
It also does not work while trying to send the getCont() to a server with send(), which is what I'm trying to use it for.

Anyone have any explanations as to why this might be happening?
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Getting a weird string return

Post by CuteAlien »

Never had that. What does it show in memory when you set a breakpoint there? Do you maybe use printf in several threads? It's not thread-safe, so you have to use mutexes around it when doing that.

Note that if your code overwrites memory at some place all kind of effects can happen. Hunting such a bug is harder. Usually you have to use divide&conquer - splitting your application up into smaller and smaller parts and testing each of those on their own until you located the problem. Or on Linux you can use a tool like Valgrind to see if it catches any errors.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Re: Getting a weird string return

Post by LunaRebirth »

Still can't figure it out. Everything seems fine except that I can't send it and can't print it. Using an if statement to compare it to what the content should be works fine.
Not overwriting any memory. Seems like an issue beyond my written code.
Looks like I'll redo some stuff and find a different way to get the results I'm looking for.
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Re: Getting a weird string return

Post by LunaRebirth »

Turns out the problem is something I can't find on Google, though I didn't try for long.
If I make a const char* and assign a value, then make a string and assign it to the const char*'s value, it sometimes messes up.
Just an example, not real data:
const char* info = "aaaa"
std::string otherInfo = info

otherInfo then holds something like "???a???aaa"
(replacing ??? with random looking symbols)

Has anyone else experienced this?
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Getting a weird string return

Post by hendu »

That's not possible. You have corrupted software or hardware.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Getting a weird string return

Post by CuteAlien »

If that's your complete code - then yeah - like hendu said - that shouldn't be. But more often when mixing pointers and string-classes the user messes up somewhere. Examples: You return a pointer to some string you created dynamically (like return std::string("bla").c_str() for a local string - that even might look like works as memory is often still there... but then your next function returns that pointer - and then you start to notice you got corruption). Or you return a pointer to a static string somewhere which buffers stuff, but you overwrite that static at some point. Then your string can look pretty much like your string (this happened to me just last week *sigh*).

What I'm trying to say - when string-pointers look like that it's nearly always a life-time thing - you are having pointers to strings which are no longer valid at this point.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Re: Getting a weird string return

Post by LunaRebirth »

Ah that could quite possibly be it. I was able to fix my getCont() function and stop the issue by creating a local variable that holds the content, then returns it. But returning the content directly is what was giving the corruption.
Seems I've found a second spot where this is occurring. Quite annoying.
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Re: Getting a weird string return

Post by LunaRebirth »

I am having this problem reoccur more often than it should.
Code as simple as

Code: Select all

char* addMediaPath(std::string dir) {
  if (dir.find("media/") != 0) {
    dir = "media/" + dir;
  }
  char* newDir = (char*)dir.c_str();
  return newDir;
}
If I call addMediaPath("media/file.txt"), I'll get some crazy result like binary-looking letters.
But it doesn't happen every time, yet it happens enough to notice that this function is creating the issue.

I'm wondering if this has to do with memory management at all. Can memory leaks cause this sort of thing? I don't see anything wonky from looking at the usage in task manager.

Edit:
I have checked variables before and after using this function.
It is for sure coming from here in my code.
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Getting a weird string return

Post by hendu »

You can't do that. You really need to read up on the C++ classes you use, those are beginner-level mistakes and you keep making the same ones, repeatedly.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Getting a weird string return

Post by CuteAlien »

To explain some more. "dir" is on the stack. That memory will be released as soon as the function has finished. Which means newDir now points to memory which is no longer valid. Anything can be written in there now (as you can see by the mess you get).

If you need to return that string you _must_ copy it. Either by returning it inside a string class like std::string (which will internally copy the string and returned variables are always on the stack of the caller function), or by creating an explicit copy the c-way (not recommended usually, something like: myVar = new char[dir.size()+1], strncpy(myVar, dir.c_str(), dir.size()+1] ... but you don't need it). C-style also means you must free the memory again when you no longer need it (hm, nice part about C is - it's pretty explicit - you learn fast that all memory _must_ be copied manually as no classes ever do that for you ^_^).

If you need to pass raw-pointer to some other library - which is the main reason you generally need them - you can return a std::string in your function. And then pass the .c_str() of that result. Because the result of the function is in the scope of the caller function (as you can see by the fact that you can call .c_str() on the result from the caller function). And the std::string will create a copy internally.

In short: Whenever you work with raw-pointers in C++ - be aware if the memory they point to is really allocated. Either with new (and not yet deleted) or it's on the stack and (that's the important part!!!) the object will *stay* on the stack as long as you use that raw-pointer to it.

If "stack" and "heap" memory confuse you - read up on it on the web until they no longer confuse you. It's important in C++ and you only have to really understand it once and then it will no longer cause troubles.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
MartinVee
Posts: 139
Joined: Tue Aug 02, 2016 3:38 pm
Location: Québec, Canada

Re: Getting a weird string return

Post by MartinVee »

Architecturally speaking, is there a specific reason to accept a C++ string class as a parameter, but returning a C-style character pointer? Why not go all the way with std::string, while you're at it?
LunaRebirth
Posts: 386
Joined: Sun May 11, 2014 12:13 am

Re: Getting a weird string return

Post by LunaRebirth »

Okay thanks for your help CuteAlien. Clearly I need to read up some more on stacks so I don't lose the memory.
hendu wrote:You can't do that. You really need to read up on the C++ classes you use, those are beginner-level mistakes and you keep making the same ones, repeatedly.
I learned C++ purely on my own Via Google :/ these must be mistakes that I never learned from because Ive never had them
MartinVee wrote:Architecturally speaking, is there a specific reason to accept a C++ string class as a parameter, but returning a C-style character pointer? Why not go all the way with std::string, while you're at it?
I thought it would be fine to do. The reason behind it is that writing a file takes a C-style character pointer, and it is easier for me to call addMediaPath("Servers/" + this->server + "/file.txt"); rather than making a local string and plugging in the c_str() of it. Through looking at the function code, this seemed like a good idea.
Post Reply