如果我有以下代碼:這個字符串的範圍是什麼?
{
UnicodeString sFish = L"FISH";
char *szFish = AnsiString(sFish).c_str();
CallFunc(szFish);
}
那麼什麼是所創建的臨時AnsiString類型的範圍,多長時間是szFish指向有效的數據嗎?對於CallFunc函數它仍然有效嗎?
它的範圍是持續一行還是整行?
如果我有以下代碼:這個字符串的範圍是什麼?
{
UnicodeString sFish = L"FISH";
char *szFish = AnsiString(sFish).c_str();
CallFunc(szFish);
}
那麼什麼是所創建的臨時AnsiString類型的範圍,多長時間是szFish指向有效的數據嗎?對於CallFunc函數它仍然有效嗎?
它的範圍是持續一行還是整行?
的C++標準的11 $ 12.2.3說:
當實現引進了類的臨時對象, 具有非簡單的構造函數(12.1,12.8),它應確保爲臨時對象調用構造函數 。類似地,應該調用析構函數臨時使用一個不重要的析構函數(12.4)。 臨時對象被作爲 中最後一步評估完整表達式(1.9)(詞法上)包含創建它們的地點的最後一步而被銷燬。即使評估 以拋出異常結束,情況也是如此。破壞臨時對象的值計算和副作用僅與 完整表達式關聯,而不與任何特定的子表達式關聯。
(重點煤礦)
還有其他注意事項這一點,但他們並不在這種情況下適用。在你的情況下,充分表達這句話的指定部分:
char *szFish = AnsiString(sFish).c_str();
// ^^^^^^^^^^^^^^^^^^^^^^^^^
因此,即時szFish
分配,你的臨時對象的析構函數(即AnsiString(sFish)
)將被調用並且其內部存儲器表示(其中c_str()
指向)將被釋放。因此,szFish
將立即成爲懸掛指針,任何訪問都將失敗。
您可以通過說出
CallFunc(AnsiString(sFish).c_str());
相反,這裏解決這個問題,臨時將(再次)的全表達後破壞(即,就在;
)和CallFunc
會能夠讀取原始字符串。
szFish
是調用CallFunc()
之前無效的,因爲AnsiString
是立即破壞和szFish
指向這將剛纔被刪除其內部緩衝區臨時對象。
確保AnsiString
實例對調用CallFunc()
有效。例如:
CallFunc(AnsiString(sFish).c_str());
我將取代:
char *szFish = AnsiString(sFish).c_str();
有:
AnsiString as(sFish);
char *szFish = as.c_str();
我不知道AnsiString
類,但在你的代碼的析構函數將您的來電之前進行發射CallFunc()
,並且很可能會釋放您指向*szFish
的字符串。當您用堆棧上的「named」對象替換臨時對象時,其生存期將延長至定義塊的末尾。
AnsiString的範圍在此情況下爲「從調用前的c_str( ),直到之後。「它可以幫助這樣設想一下:
char *szFish;
{
AnsiString tmpString(sFish);
szFish = tmpString.c_str();
}
不熟悉'UnicodeString'或'AnsiString',但字符串必須至少持續到塊結束。 –