简体   繁体   中英

Can't successfully return a const char* I have created by calling c_str() on a string. (C++)

I have a class in my program that has a member variable, an int called number, and a member function, getName(), that is MEANT to return the words "Dice: #" as a const char*, but with the # replaced by the number stored in the class.

const char* getName(){
 return "Dice:";
}

works perfectly well.

const char* getName(){
 std::stringstream ss;
 ss << number;
 std::string s;
 s = "Dice: " + ss.str();
 return s.c_str();
}

does NOT work fine, and returns what seems to be garbage. I can't figure out the correct way to go about this. If I use cout to print s.c_str() it prints what I expect.

The short and sweet answer is that you can't do this, the way you've set this up.

The std::string object from which you retrieve your c_str() is in the function's local scope. When the function returns that std::string object gets destroyed.

That

std::string s;

is a local function object. When the function returns it ceases to exist. It joins the choir invisible. It is no more. It's an ex-object.

And when a std::string object gets destroyed, any of its c_str() s are no longer valid. This is why you're getting garbage: undefined behavior.

There is no way to do this without changing the overall design of it, in some way. There are many ways to go forward. Some of the possibilities:

Return a std::string in the first place

Just return the std::string from getName() . Whoever calls it can store this std::string , for a while, and grab it's c_str() if it needs it.

Use a std::string with a different scope

If this getName() is a class method, you could have a private std::string class member, have getName() store the string there, and return its c_str() .

Because the original std::string continues to exist, the returned c_str() remains valid. Note that there are some pitfalls here. If the caller calls getName() again, the previously-returned c_str() will no longer be valid.

Conclusion

Just get in the habit of using and working with std::string s in your C++ code. That's what they're for.

The name "c_str()" should be a clue. It gives you a string to be used with C code, if there's any C code lying around, in the near vicinity. It's a C string. Are you writing C code here? No, you're writing C++ code.

Unless you're writing C code, or are talking to a C library, there's no need to use c_str () in the first place. If you're writing C++ code, you should be using std::string s. If you need to call a C library function, call c_str() to pass the appropriate C library function parameter, and speak of this C string no more.

You are creating a local variable 's' and then returning a pointer to the strig withing the string memory.

When the function returns the string goes out of scope (and so does the pointer)

Best bet is probally change getname to return a std::string, and then if you need to use the c_str, use it where it is returned.

std::string name = object.getName();
printf("name = %s", name.c_str());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM