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;
}
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);