Why does calling c_str() on a function that returns a string not work?

SomeFunction().c_str() gives you a pointer to a temporary(the automatic variable str in the body of SomeFunction). Unlike with references, the lifetime of temporaries isn't extended in this case and you end up with charArray being a dangling pointer explaining the garbage value you see later on when you try to use charArray.

On the other hand, when you do

string str_copy = SomeFunction();

str_copy is a copy of the return value of SomeFunction(). Calling c_str() on it now gives you a pointer to valid data.


The value object returned by a function is a temporary. The results of c_str() are valid only through the lifetime of the temporary. The lifetime of the temporary in most cases is to the end of the full expression, which is often the semicolon.

const char *p = SomeFunction();
printf("%s\n", p); // p points to invalid memory here.

The workaround is to make sure that you use the result of c_str() before the end of the full expression.

#include <cstring>

char *strdup(const char *src_str) noexcept {
    char *new_str = new char[std::strlen(src_str) + 1];
    std::strcpy(new_str, src_str);
    return new_str;
}

const char *p = strdup(SomeFunction.c_str());

Note that strdup is a POSIX function, so if you are a platform that supports POSIX, it's already there.