Problems with certain type conversions in c++

0

I am using box2d(however this question is probably only about c++ itself) and there is a member variable which is pointer to void, like this:

void* userData;

You can get the userData by the getUserData(), which returns a a void pointer.

I want to store a string as the userData and there is set the userData to the string like so:

std::string user = "player";
playerDef.userData = &user;

Then I am trying to get the userData by doing this:

std::string* sd = (std::string*)bb->GetUserData();

(where "bb" is a pointer to the entity holding these information)

Finally, I try to use the function c_str() in order to get what is compatible for my purposes but then I get the error: Access violation reading location 0x00000070

I also want to be able to do the same thing but with a char array but I am doing this:

char user[] = "player";
playerDef.userData = &user;

char* sd[] = (char*)bb->GetUserData();

The third step gives the error: Cannot convert from 'char' to 'char*[]'*

I could already feel by looking at this approach on the char part that something was wrong but I do not know what...

I did the same thing with integers like this:

int user[] = int;
playerDef.userData = &user;

int* sd = (int*)bb->GetUserData();

and that worked just great.

So my questions are the following:

  • What am I doing wrong with the std::string part?
  • What is wrong with the char part and how to achieve the char array that I want?
  • How come that the integer part works then :/ (I know that it is not an array though)?

Note: I would be more than happy to get extra thoughts on possible optimizations in general, like user static_cast or something.

Thanks! It is really appreciated, like very much!

Cheers.

c++
asked on Stack Overflow Feb 27, 2017 by (unknown user) • edited Feb 27, 2017 by (unknown user)

1 Answer

1
std::string user = "player";
playerDef.userData = &user;

When whatever function sets this pointer here returns, user, the std::string object, gets destroyed. The fact that there's a pointer to this std::string, somewhere, doesn't change that.

Your subsequent attempt to use this pointer fails miserably, since, obviously, the string has been destroyed, and the pointer points to garbage.

And when you use an int array, that was broken also. The fact that your program didn't crash in that case doesn't change that this was undefined behavior, and a bug.

This is a common situation when integrating C++ code with a generic C library, that knows nothing about C++ classes, where all that it offers you to work with is an opaque, bland void pointer. There are several ways of doing this correctly. A common way is to use dynamic scope:

playerDef.userData = new std::string;
*playerDef.userData = "player";

Later you can dereference this pointer, having some degree of confidence that the pointed-to object still exist, and hasn't been nuked from high orbit.

Of course, now you will need to make sure that at some point this is going to get deleted, otherwise you'll leak memory. But this is often the best that can be done when working with a C library's opaque pointers.

answered on Stack Overflow Feb 27, 2017 by Sam Varshavchik

User contributions licensed under CC BY-SA 3.0