Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to call temporary object's methods?

Tags:

c++

string

g++

stl

I have a function which shall return a char*. Since I have to concatenate some strings, I wrote the following line:

std::string other_text;
// ...
func(("text" + other_text).c_str());

I know that I could avoid the question naming the string I want to use. I just want to take the chance to make a more general question: is it safe to call methods of temporary variables? is it standard compliant?

like image 433
Emiliano Avatar asked Mar 31 '09 14:03

Emiliano


2 Answers

A generated pointer will be good for as long as the temporary is still around, which is normally until the end of the expression. The exceptions are when a temporary is used in an initializer (in which case it lasts until the initialization is over), or when bound to a reference. A temporary in a function return statement lasts until the function exits (unless bound to a reference). Once the temporary lifetime is over, the temporary is destroyed. In this case, it means that the string destructor runs, and therefore the memory for the characters is freed. In other words, once the value is returned, it's guaranteed invalid.

You could pass the string itself back, returning it as a const reference. You could copy the .c_str() to newly allocated memory, and pass that back (as a pointer or smart pointer). Either of those would work.

The lifetime of temporaries is covered in section 12.2 of the C++ standard. According to the standard, you're returning a pointer to freed memory.

like image 121
David Thornley Avatar answered Sep 30 '22 04:09

David Thornley


It is safe to call methods of temporary variables, but not safe to return a char* of a temporary variable for later use.

This char* points to a buffer that will be freed soon. Once it is freed you will have a pointer to an invalid region in memory.

Instead please return an std::string object.

like image 26
Brian R. Bondy Avatar answered Sep 30 '22 03:09

Brian R. Bondy