Search code examples
c++stdstring

c++ std::string use overwrites values


What am I doing wrong here? Apparently aval is overwritten when I call getbbb. Expected output is:

test A aval: "aaa"
test B aval: "aaa"

Actual output is:

test A aval: "aaa"
test B aval: "bbb"

File testb.c:

#include <string>

// g++ -o tempa testb.c && ./tempa

std::string getaaa() {
  return std::string("aaa");
}

std::string getbbb() {
  return std::string("bbb");
}

int main(
  int argc,               // num args, including pgm name
  char * argv[])          // args
{
  const char * aval = getaaa().c_str();
  printf("test A aval: \"%s\"\n", aval);

  getbbb();

  printf("test B aval: \"%s\"\n", aval);
  return 0;

}

Solution

  • const char * aval = getaaa().c_str(); leads to undefined behavior.

    getaaa() returns a temporary string object that is destroyed when the full expression that created it is finished (ie, on the ;), which is after you have grabbed the string's data pointer. Thus, the pointer is left dangling, pointing at freed memory. Any subsequent reading from that pointer is undefined behavior.

    Since the string object from getaaa() is destroyed and its data freed before getbbb() is called, getbbb() is allowed to reuse the same memory for its own string object. This is not guaranteed, but it is possible (and clearly the case in your situation).

    To solve this, save the temporary string object from getaaa() to a local string variable before grabbing the pointer:

    const string sval = getaaa();
    const char * aval = sval.c_str();
    
    printf("test A aval: \"%s\"\n", aval);
    
    getbbb();
    
    printf("test B aval: \"%s\"\n", aval);