2010-10-22 196 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

字符串文字具有靜態存儲,所以在函數結束時不會被釋放。