2012-04-28 107 views
1

我現在在閱讀「C++標準庫」。當我閱讀字符串的章節時,我遇到了一個問題。 它告訴我們,如果內容是由data()導出的,那麼引用字符串字符的引用和指針就會失效。C++字符串數據()函數使引用和指針無效?

enter image description here

,因爲我們知道,數據()返回字符串的內容作爲字符數組和因爲沒有「\ 0」字符被所附的返回類型不是有效的C-字符串。

但爲什麼data()使引用和指針無效?

有人能爲我解釋嗎?非常感謝!

+0

由於緩衝區本身需要包含一個,因此C++ 11中的IIRC'data'確實包含一個「'\ 0'」。 – Pubby 2012-04-28 10:30:45

+0

但「C++標準庫」在C++ 11之前發佈。 – XiaJun 2012-04-28 10:44:25

回答

4

調用data本身不,調用可變方法(非const)之後可能會使先前的指針無效。這是因爲當你修改字符串時,內部字符數組可能會被更改或重新分配。

0

一個例子,假定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」,或者可能會將蘋果酒噴到耳中。

0

我讀最後一個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,所以它不應該無效東西。

+0

@Downvoter - 如何解釋,我的答案有什麼問題? – 2012-04-28 11:24:48

1

在C++ 03中,並不要求內部字符串表示必須是連續緩衝區。它也被允許與另一個字符串共享內部信息(例如使用引用計數)。

因此,調用data()c_str()可能會強制字符串重構其內部數據,以便能夠返回指向char緩衝區的指針。