views:

59

answers:

2
const char *Greet(const char *c) {
    string name;
    if(c)
        name = c;
    if (name.empty())
        return "Hello, Unknown";
    return name.c_str();
}

int _tmain(int argc, _TCHAR* argv[])
{
    cout << Greet(0) << '\t' << Greet("Hello, World") << endl;
    return 0;
}

I see 2 bugs with the above code.

  1. Returning c_str from a string object that is defined local to the function. String gets destroyed when function returns and clearly c_str() will point to some memory that is de-allocated.

  2. Returning "Hello, Unknown" from within the function. This is again an array of const chars allocated in the stack which should get de-allocated as well when the function returns. However, it does not and I am guessing that is because of Return Value Optimization.

Is my above understanding correct?

PS: I tested the above code with both gcc and MSVC10. GCC runs the above code fine and does not generate any runtime errors or undefined behaviors both for the string object as well as for the constant string. MSVC10 displays garbage data for the string object but prints the constant string correctly.

+11  A: 

Number 1 is correct. The pointer returned from c_str() is invalidated when name is destroyed. Dereferencing the pointer after name results in undefined behavior. In your tests, under gcc it appears to work; under Visual C++ it prints garbage. Any results are possible when the behavior is undefined.

Number 2 is incorrect. "Hello, Unknown" is a string literal. String literals have static storage duration (they exist from when the program starts up to when it terminates. You are returning a pointer to this string literal, and that pointer is valid even after the function returns.

James McNellis
+1  A: 

String literals have static storage, so are not deallocated at the end of the function.

Oli Charlesworth