2011-04-22 62 views
2

這是明確定義的行爲嗎?臨時表達行爲

const char* p = (std::string("Hello") + std::string("World")).c_str(); 
std::cout << p; 

我不確定。原因是什麼?

回答

6

不,這是未定義的行爲。臨時文件std::string和臨時文件operator+返回的臨時文件只有在您的const char*(完整表達式結束)初始化結束時纔會生效。然後它們被銷燬並且指向不確定的記憶。

+2

每個人都只贊@Johannes(儘管@Prasoon引用了參考文獻)。非常不公平。 :P – Nawaz 2011-04-22 15:29:08

+1

@Nawaz:你能做什麼,Johannes是這裏的名人...... – fredoverflow 2011-04-22 15:32:09

+1

@Nawaz:引用Herb Sutter,「這個標準不是真正的人們閱讀的教程。」除非有人明確要求引用規範或主題如此技術性以至於需要引用,否則最好將規範留給答案。只是複製一段沒有解釋的段落(什麼是「定義一個對象的聲明的初始化器」?)並不是特別有用。 – 2011-04-22 15:55:46

2

無行爲是不確定的,因爲p指向std::cout << p;

創建持有std::string("Hello") + std::string("World")臨時釋放存儲空間。 C風格的字符串然後從該對象中回收。在表達式結尾處,臨時被銷燬,離開p指向一個釋放存儲。使用p然後調用未定義的行爲。

12.2/4說

存在其中的臨時被在不同的點比全表達式的結尾破壞兩個上下文。第一個上下文是當表達式作爲定義對象的聲明符的初始化符出現時。在這種情況下,保留表達式結果的臨時表將一直保留,直到對象的初始化完成爲止 。
....

+2

您突出顯示的位並不明顯。包含用作初始值設定項的表達式的臨時數據類型爲'const char *'類型的臨時類型,其中包含來自'c_str()'的返回值。你所引用的內容說* *臨時存在,直到初始化完成,它不會說表達式中的所有臨時對象(包括字符串)都會一直存在,直到初始化完成... – 2011-04-22 18:36:37

+0

...儘管我認爲這暗示了其他地方,也許是關於臨時被破壞的創造逆序的東西?不確定。 – 2011-04-22 18:43:43

1

因爲缺少分號的它不會編譯:

const char* p = (std::string("Hello") + std::string("World")).c_str(); //<< important here 
std::cout << p; 

現在的規則適用,臨時在其使用的表達,這是分號結束時刪除。所以你有一個指向刪除內存的指針,導致未定義的行爲。