這是明確定義的行爲嗎?臨時表達行爲
const char* p = (std::string("Hello") + std::string("World")).c_str();
std::cout << p;
我不確定。原因是什麼?
這是明確定義的行爲嗎?臨時表達行爲
const char* p = (std::string("Hello") + std::string("World")).c_str();
std::cout << p;
我不確定。原因是什麼?
不,這是未定義的行爲。臨時文件std::string
和臨時文件operator+
返回的臨時文件只有在您的const char*
(完整表達式結束)初始化結束時纔會生效。然後它們被銷燬並且指向不確定的記憶。
無行爲是不確定的,因爲p
指向std::cout << p;
創建持有std::string("Hello") + std::string("World")
臨時釋放存儲空間。 C風格的字符串然後從該對象中回收。在表達式結尾處,臨時被銷燬,離開p
指向一個釋放存儲。使用p
然後調用未定義的行爲。
12.2/4說
存在其中的臨時被在不同的點比全表達式的結尾破壞兩個上下文。第一個上下文是當表達式作爲定義對象的聲明符的初始化符出現時。在這種情況下,保留表達式結果的臨時表將一直保留,直到對象的初始化完成爲止 。
....
您突出顯示的位並不明顯。包含用作初始值設定項的表達式的臨時數據類型爲'const char *'類型的臨時類型,其中包含來自'c_str()'的返回值。你所引用的內容說* *臨時存在,直到初始化完成,它不會說表達式中的所有臨時對象(包括字符串)都會一直存在,直到初始化完成... – 2011-04-22 18:36:37
...儘管我認爲這暗示了其他地方,也許是關於臨時被破壞的創造逆序的東西?不確定。 – 2011-04-22 18:43:43
因爲缺少分號的它不會編譯:
const char* p = (std::string("Hello") + std::string("World")).c_str(); //<< important here
std::cout << p;
現在的規則適用,臨時在其使用的表達,這是分號結束時刪除。所以你有一個指向刪除內存的指針,導致未定義的行爲。
我最近讀了這本優秀的書http://www.amazon.co.uk/Gotchas-Avoiding-Addison-Wesley-Professional-Computing/dp/0321125185/ref,如果我正確地記得,這幾乎是其中的一個例子。
我相信從c_str
返回的數據只有在返回它的字符串對象是活的時纔有效。您的示例中的字符串對象只在表達式的持續時間內有效。
每個人都只贊@Johannes(儘管@Prasoon引用了參考文獻)。非常不公平。 :P – Nawaz 2011-04-22 15:29:08
@Nawaz:你能做什麼,Johannes是這裏的名人...... – fredoverflow 2011-04-22 15:32:09
@Nawaz:引用Herb Sutter,「這個標準不是真正的人們閱讀的教程。」除非有人明確要求引用規範或主題如此技術性以至於需要引用,否則最好將規範留給答案。只是複製一段沒有解釋的段落(什麼是「定義一個對象的聲明的初始化器」?)並不是特別有用。 – 2011-04-22 15:55:46