问题
I have a method defined as below:
const std::string returnStringMethod()
{
std::string myString;
// populate myString
return myString;
}
Now, in the caller, I was doing something like this:
const char * ptr = returnStringMethod().c_str();
As I can see this is returning some truncated string which I did not expect. However, the folllowing works fine:
std::string str = returnStringMethod();
const char * ptr = str.c_str();
Can someone please help me understand whats happening here? .
PS: We build code once a week. I tested this when I was submitting my code last week and things were fine. So, I really wanted to know what I might be missing here.
thanks, Pavan.
回答1:
The first is undefined behavior, the temporary returnStringMethod()
is valid only until the trailing ;
, so the internal string (returned by c_str()
) is destroyed, so you're left with a dangling pointer.
The second version is valid because str
will be destroyed when its scope ends, and its scope is the same as ptr
(at least in your example).
For example, the following would also be wrong:
const char * ptr = NULL;
{
std::string str = returnStringMethod();
ptr = str.c_str();
}
After }
, ptr
is no longer valid.
回答2:
The return value of returnStringMethod
is a temporary string, the lifetime of which is bound to the expression itself; this means that the std::string
on which you call c_str
will be destructed right after ptr
has been initialized in const char * ptr = returnStringMethod ().c_str ()
.
The implications of this is that the value which ptr
has been initialized with points to memory which is no longer accessible.
In the latter case, where you assign the returned value of returnStringMethod
to std::string str
you will have a copy which lifetime is bound to the current scope. Assigning the value of str.c_str ()
to ptr
is therefor valid for as long as str
is alive.
回答3:
const char * ptr = returnStringMethod().c_str();
In above line a temp string is returned by the function which soon goes out of scope. (and destructor is called and memory is freed)
In later version you make a local copy of string and thus the behaviour is defined.
You can also use the following
const std::string &str = returnStringMethod();
const char * ptr = str.c_str();
Using const reference would lengthen the life of temporary variable until the reference is in scope and there would be no (explicit) unwanted copies.
回答4:
You're returning a (temporary) copy and that's where you execute the c_str().
When the temporary goes away, the char * returned by the c_str() becomes invalid.
来源:https://stackoverflow.com/questions/23869552/improper-use-of-c-str