2012-04-04 41 views
45

是對以下C++代碼合式:的std :: string :: c_str()和臨時

void consumer(char const* p) 
{ 
    std::printf("%s", p); 
} 

std::string random_string_generator() 
{ 
    // returns a random std::string object 
} 

consumer(random_string_generator().c_str()); 

我與它的問題是,創建臨時的std :: string對象和服用後c_str()指針,什麼都不能阻止std :: string對象被破壞(或者我錯了?)。你能指點我的標準嗎,如果代碼是好的,儘管一切。它工作,當我用g ++測試時。

回答

56

std::string::c_str()返回的指針指向由字符串對象維護的內存 。直到在字符串對象上調用非const 函數或字符串對象爲 遭到破壞,它纔有效。你關心的字符串對象是一個臨時對象。 它將在完整表達式的末尾被破壞,而不是在之前和之後。在你的情況下,完整表達式的結尾在 調用consumer之後,所以你的代碼是安全的。如果consumer 將指針保存在某處,並且稍後使用它,則不是。

從C++ 98開始,臨時對象的生命週期就被嚴格定義了。 在此之前,它有所不同,這取決於編譯器,並且您編寫的代碼不會與g ++一起使用(1995年以前,大致— g ++ 在標準委員會投票決定時幾乎立即改變了這一點)。 (當時還沒有std::string,但同樣的問題影響 任何用戶寫入的字符串類。)

18

臨時std::string的壽命延長剛剛超越的地步consumer回報,因此它是安全的從consumer內該字符串直接使用任何東西。什麼是而不是好的是存儲c_str返回的值,並在稍後嘗試使用它(臨時將被銷燬,我們只能猜測在指針的另一端會發現什麼)。

+1

您能否提供關於C++ 03或C++ 11標準的提示? – user1095108 2012-04-04 07:53:01

+3

臨時的生命週期在§12.2中定義。 (第12部分是 ,標題爲「特殊成員函數」,它不是 期望尋找臨時對象的生命期的地方,但這就是它的位置。) – 2012-04-04 07:56:24

+0

@ user1095108函數參數的生命週期可以從§ 3.2.2和§3.7.2在C++ 03標準中。 – juanchopanza 2012-04-04 08:24:46

5

函數random_string_generator()返回的臨時函數可安全地用於consumer()函數。

相關問題