2017-09-15 83 views
-7

考慮下面的代碼片段:什麼是C++字符串的默認容量?

string line; 
line = ""; 
cout << line[400] << endl; //Works, random character 
cout << line[20000] << endl; //Segmentation Fault 

看起來像C++字符串有一個默認的能力,以防止到達邊界之外,當不好的事情發生。但我無法找到關於此主題的更多資源。

我在mac環境下編譯了clang代碼片段。

+5

有標準沒有定義默認容量。 – Galik

+8

你遇到的錯誤不是因爲字符串有'默認容量',這是因爲你在隨機存儲器周圍。 – pvg

+0

@Galik當你做line.capacity()時,它會返回22,但是肯定會發生更多的事情發生在這裏 –

回答

2

那麼,標準根本沒有給出默認容量。

雖然許多實現都是小型字符串優化(SSO),所以它們具有(相對較小的)最小容量而沒有任何額外的分配。

您所遇到的事情與此無關:
未定義的行爲

正如名字所說,無論您是否期望,都可能發生任何事情。你的字符串後備存儲可能被更多的可尋址內存所包圍,但是你的任意讀取是否會觸及它,這是任意的。

+0

事實上,OP獲得的'capacity()'的結果是來自SSO。 https://wandbox.org/permlink/Ii7bNqR6scDRoist – Justin

1

正如評論中所解釋的那樣,標準中沒有定義默認容量,所以對於您的直接問題的答案是「沒有一個」。 你看到的結果只是未定義的行爲,所以不能得出有用的結論。


然而,嘗試回答隱含的潛在的問題(「這是怎麼回事?」),當一個頁面邊界侵犯分割故障通常發生 - 訪問「時,無法超越什麼應該被分配到變量「,因此這裏的容量實際上並不相關。

你可能看到的是line.c_str() + 400仍然在頁面上,但是當你進一步去20000字節時,你可能會偏離目標,所以你得到了SigSeg。但是,是的,未定義的行爲錘降下來,並把這一切都推測爲猜測。

0

還有很多人說過,使用operator[]方法訪問std::string超出字符串大小的方法是未定義的行爲。當遇到未定義的行爲時,程序被允許執行任何操作,直到幷包括刪除所有文件。 (它不會,但它被允許。)要安全地訪問一個字符,可能會或可能不會是字符串的邊界之外,使用at代替operator[]

但是,要回答您的原始問題,可以通過在字符串上調用max_size()來確定std::string的最大大小。詳情請參閱max_size()

+0

max_size()不是我很感興趣的,capacity()更相關。 –

相關問題