2010-10-22 146 views
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; 
} 

我看到2个错误与上面的代码。从函数返回值

  1. 从函数本地定义的字符串对象中返回c_str。当函数返回时,字符串被破坏,显然c_str()会指向一些被解除分配的内存。

  2. 从函数内返回“Hello,Unknown”。这又是一个在堆栈中分配的常量字符数组,它应该在函数返回时被解除分配。然而,它并没有,我猜这是因为返回值优化。

我的上述理解是否正确?

PS:我用gcc和MSVC10测试了上面的代码。 GCC运行上述代码并且不会为字符串对象以及常量字符串生成任何运行时错误或未定义的行为。 MSVC10显示字符串对象的垃圾数据,但正确输出常量字符串。

+0

那么,技术上GCC对'Greet(“Hello,World”)的行为是'undefined – AlcubierreDrive 2010-10-22 23:45:39

回答

11

数字1是正确的。从c_str()返回的指针在销毁name时失效。在name之后解引用指针会导致未定义的行为。在你的测试中,在gcc下出现工作;在Visual C++下打印垃圾。当行为未定义时,任何结果都是可能的。

2号错误。 "Hello, Unknown"是一个字符串文字。字符串文字具有静态存储持续时间(它们存在于从程序启动到结束时,您正在返回一个指向该字符串文字的指针,并且该指针在函数返回后仍然有效。

1

字符串文字具有静态存储,所以在函数结束时不会被释放。