For Code:
stringstream ss("012345678901234567890123456789012345678901234567890123456789");
some articles said it is wrong for followed usage due to ss.str return temp object and will destructered before call .c_str();
const char* cstr2 = ss.str().c_str();
but I run the example, there is no problem? how to understand?
But I run the example, there is no problem?
In fact, there's nothing wrong in the expression:
const char* cstr2 = ss.str().c_str();
The temporary (copy) object returned by ss.str()
will live long enough to let you get the underlying c-string with c_str()
.
Of course by the end of the expression you'll have a const char
pointer to an object that is probably deallocated (this depends heavily on the std::basic_string
implementation).
Therefore this is likely not a good idea. What you should do instead is:
auto x = ss.str();
const char* cstr2 = x.c_str();
The above code won't get you any trouble, since the returned value of str()
is now being copied/is not a temporary anymore, and the access to x.c_str()
will give you a valid pointer.
Yet another wonderful C++ landmine.
Basically, your pointer references a block of memory (C string) that is referencing a temporary copy (string) of whatever was in the stream at the time you did the double affectation.
str() returns a temporary object.
Life expectancy of temporary objects is rather short. Either someone takes a reference to them immediately (e.g. string& s = ss.str()
) or they die at the end of the statement they were born in.
However, the compiler allows to get a reference to the same block of memory through c_str(), but indirectly, so it flies under the compiler's radar. What a pity.
So your pointer will indeed be valid at the time c_str gets it, but just for about as long as if you did something like this in plain old C:
const char * cstr2;
{
char ss_str[100]; // str() return value is dynamically created
char * c_str = &ss_str_[10]; // c_str() takes a reference to some part of it
cstr2 = c_str; // cstr2 takes an indirect reference to str() ret. val.
} // compiler pulls the plug on str() ret. val.
So, right after the end of this very statement, c_str is already referencing the cadaver of whatever string str() returned.
Now since temporary objects are allocated on the stack, you may well never notice the problem. Object deallocation in itself will likely not modify the defunct string value, but as soon as the compiler will reuse this bit of stack, the proverbial guru will have something to meditate over.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With