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;
}
我看到上面代码有2个错误。
从函数本地定义的字符串对象返回c_str。函数返回时字符串被销毁,显然c_str()将指向一些已解除分配的内存。
从函数中返回“Hello,Unknown”。这又是在堆栈中分配的const char数组,当函数返回时,它也应该被解除分配。但是,它没有,我猜这是因为返回值优化。
我的上述理解是否正确?
PS:我用gcc和MSVC10测试了上面的代码。 GCC运行上面的代码很好,并且不会为字符串对象和常量字符串生成任何运行时错误或未定义的行为。 MSVC10显示字符串对象的垃圾数据,但正确打印常量字符串。
答案 0 :(得分:11)
1号是正确的。当c_str()
被销毁时,从name
返回的指针无效。在name
之后取消引用指针会导致未定义的行为。在你的测试中,在gcc下它出现工作;在Visual C ++下它打印垃圾。当行为未定义时,任何结果都是可能的。
2号不正确。 "Hello, Unknown"
是一个字符串文字。字符串文字具有静态存储持续时间(它们从程序启动到终止时存在。您将返回指向此字符串文字的指针,即使在函数返回后该指针仍然有效。
答案 1 :(得分:1)
字符串文字具有静态存储,因此不会在函数末尾取消分配。