我現在在閱讀「C++標準庫」。當我閱讀字符串的章節時,我遇到了一個問題。 它告訴我們,如果內容是由data()導出的,那麼引用字符串字符的引用和指針就會失效。C++字符串數據()函數使引用和指針無效?
,因爲我們知道,數據()返回字符串的內容作爲字符數組和因爲沒有「\ 0」字符被所附的返回類型不是有效的C-字符串。
但爲什麼data()使引用和指針無效?
有人能爲我解釋嗎?非常感謝!
我現在在閱讀「C++標準庫」。當我閱讀字符串的章節時,我遇到了一個問題。 它告訴我們,如果內容是由data()導出的,那麼引用字符串字符的引用和指針就會失效。C++字符串數據()函數使引用和指針無效?
,因爲我們知道,數據()返回字符串的內容作爲字符數組和因爲沒有「\ 0」字符被所附的返回類型不是有效的C-字符串。
但爲什麼data()使引用和指針無效?
有人能爲我解釋嗎?非常感謝!
調用data
本身不,調用可變方法(非const
)之後可能會使先前的指針無效。這是因爲當你修改字符串時,內部字符數組可能會被更改或重新分配。
一個例子,假定C++ 11(使得data()
保證是空終止):
string s = "abc" ;
const char* p = s.data() ;
cout << p << endl ;
s = "ABCDE" ;
cout << p << endl ;
第二分配到s
無效p
,因爲s
威力(在此,它很可能會)重新分配其內部緩衝區。所以最後的cout
的結果是未定義的。它可能會打印「abc」或「ABCDE」,或者可能會將蘋果酒噴到耳中。
我讀最後一個C++ 11條草案,並不能找到任何會支持這樣的主張:
21.4.1第6部分:參考文獻,指針和迭代器引用的元素basic_string序列可以通過以下basic_string對象的使用而失效:
- 作爲任何引用非const basic_string作爲參數的標準庫函數的參數。
- 調用非const成員函數,除operator [],at,front,back,begin,rbegin,end和rend。
而且腳註第一點:
例如,作爲參數傳遞給非成員函數交換()(21.4.8.8),操作員>>()(21.4.8.9),和函數getline()(21.4.8.9),或作爲一個參數的basic_string ::互換()
data()
成員函數聲明const
,所以它不應該無效東西。
@Downvoter - 如何解釋,我的答案有什麼問題? – 2012-04-28 11:24:48
在C++ 03中,並不要求內部字符串表示必須是連續緩衝區。它也被允許與另一個字符串共享內部信息(例如使用引用計數)。
因此,調用data()
或c_str()
可能會強制字符串重構其內部數據,以便能夠返回指向char緩衝區的指針。
由於緩衝區本身需要包含一個,因此C++ 11中的IIRC'data'確實包含一個「'\ 0'」。 – Pubby 2012-04-28 10:30:45
但「C++標準庫」在C++ 11之前發佈。 – XiaJun 2012-04-28 10:44:25