Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::string::c_str() and temporaries

Tags:

c++

stl

stdstring

Is the following C++ code well-formed:

void consumer(char const* p) {   std::printf("%s", p); }  std::string random_string_generator() {   // returns a random std::string object }  consumer(random_string_generator().c_str()); 

The problem I have with it is, that after creating the temporary std::string object and taking the c_str() pointer, nothing prevents the std::string object from getting destroyed (or maybe I'm wrong?). Can you please point me to the standard, if the code is OK despite everything. It does work, when I test with g++.

like image 843
user1095108 Avatar asked Apr 04 '12 07:04

user1095108


People also ask

What is the purpose of the c_str () member function of std::string?

std::string::c_strReturns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object.

What is string c_str ()?

The basic_string::c_str() is a builtin function in C++ which returns a pointer to an array that contains a null-terminated sequence of characters representing the current value of the basic_string object.

What does c_str () do in C++?

The c_str() method converts a string to an array of characters with a null character at the end. The function takes in no parameters and returns a pointer to this character array (also called a c-string).

Is string c_str null-terminated?

c_str returns a "C string". And C strings are always terminated by a null character. This is C standard.


2 Answers

The pointer returned by std::string::c_str() points to memory maintained by the string object. It remains valid until a non-const function is called on the string object, or the string object is destructed. The string object you're concerned about is a temporary. It will be destructed at the end of the full expression, not before and not after. In your case, the end of the full expression is after the call to consumer, so your code is safe. It wouldn't be if consumer saved the pointer somewhere, with the idea of using it later.

The lifetime of temporaries has been strictly defined since C++98. Before that, it varied, depending on the compiler, and the code you've written wouldn't have worked with g++ (pre 1995, roughly—g++ changed this almost immediately when the standards committee voted it). (There wasn't an std::string then either, but the same issues affect any user written string class.)

like image 60
James Kanze Avatar answered Sep 19 '22 18:09

James Kanze


The temporary std::string's lifetime extends just beyond the point where consumer returns, so it is safe to use anything on that string directly from within consumer. What is not OK is to store the value that c_str returns and try to use it later (the temporary will have been destroyed, and we can only guess what you will find at the other end of the pointer).

like image 37
Jon Avatar answered Sep 21 '22 18:09

Jon