I've got a rather basic C++ question, consider a function that takes some input parameters and creates a std::string
that from those parameters like the one below:
std::string constructString( int some_parameter ) {
std::stringstream ss;
// Construct a string (arbitrarily complex)
ss << "Some parameter is " << some_parameter << " right now";
return ss.str(); //Am I not returning a temporary object here?
}
I understand that the stringstream-object will go out of scope when the function returns, but doesn't that invalidate the constructed string as well?
What would happen if I changed the return type to const char *
and returned ss.str().c_str()
instead?
Code like the above seems to work, but I suspect that's just because the memory containing the 'temporary' object has not yet been overwritten with something else when I use it?
I have to admit, I'm rather confused in such situations in general, I'd appreciate it if someone could explain this whole "temporary objects"-thing to me (or just point me in the right direction).
thx in advance
You are returning a temporary object, but because you return it by value, the copy is created. If you return pointer or reference to temporary object, that would be a mistake.
If you change the return type to const char *
and return ss.str().c_str()
you would return pointer to some buffer of temporary std::string
returned by ss.str()
and that would be bad.
As you see Stringstream::str() returns std::string
object. You returns std::string
without reference that means that without RVO(NRVO) optimization copy constructor will call and create valid std::string
object. With optimization std::string
will be moved without copy constructor. But if will return std::string&
it will crash because this object will be destroyed after function return. Same effect will be with const char *
because after destroying this pointer will point on bad memory and this is dangerous situation.
Assume this: T val = some_function()
, when you return a value from some_function
C++ copy value of returned value into val
using specified copy constructor or built-in operator. So if you return an int
or std::string
there is no problem at all, but if you return a pointer to a memory that will be freed at end of the function, oops!! your pointer will be pointed to an invalid memory. For example consider this:
const char* some_function() {
std::string res( ... );
//...
return res.c_str();
}
You are returning pointer to data that will be freed as soon as function return(since res
will be destroyed and it will free its internal data) so you will get the address, but that address does not point to what you possibly expect!