考慮下面的代碼片段:什麼是C++字符串的默認容量?
string line;
line = "";
cout << line[400] << endl; //Works, random character
cout << line[20000] << endl; //Segmentation Fault
看起來像C++字符串有一個默認的能力,以防止到達邊界之外,當不好的事情發生。但我無法找到關於此主題的更多資源。
我在mac環境下編譯了clang代碼片段。
考慮下面的代碼片段:什麼是C++字符串的默認容量?
string line;
line = "";
cout << line[400] << endl; //Works, random character
cout << line[20000] << endl; //Segmentation Fault
看起來像C++字符串有一個默認的能力,以防止到達邊界之外,當不好的事情發生。但我無法找到關於此主題的更多資源。
我在mac環境下編譯了clang代碼片段。
那麼,標準根本沒有給出默認容量。
雖然許多實現都是小型字符串優化(SSO),所以它們具有(相對較小的)最小容量而沒有任何額外的分配。
您所遇到的事情與此無關:
未定義的行爲。
正如名字所說,無論您是否期望,都可能發生任何事情。你的字符串後備存儲可能被更多的可尋址內存所包圍,但是你的任意讀取是否會觸及它,這是任意的。
事實上,OP獲得的'capacity()'的結果是來自SSO。 https://wandbox.org/permlink/Ii7bNqR6scDRoist – Justin
正如評論中所解釋的那樣,標準中沒有定義默認容量,所以對於您的直接問題的答案是「沒有一個」。 你看到的結果只是未定義的行爲,所以不能得出有用的結論。
然而,嘗試回答隱含的潛在的問題(「這是怎麼回事?」),當一個頁面邊界侵犯分割故障通常發生 - 訪問「時,無法超越什麼應該被分配到變量「,因此這裏的容量實際上並不相關。
你可能看到的是line.c_str() + 400
仍然在頁面上,但是當你進一步去20000字節時,你可能會偏離目標,所以你得到了SigSeg。但是,是的,未定義的行爲錘降下來,並把這一切都推測爲猜測。
還有很多人說過,使用operator[]
方法訪問std::string
超出字符串大小的方法是未定義的行爲。當遇到未定義的行爲時,程序被允許執行任何操作,直到幷包括刪除所有文件。 (它不會,但它被允許。)要安全地訪問一個字符,可能會或可能不會是字符串的邊界之外,使用at
代替operator[]
。
但是,要回答您的原始問題,可以通過在字符串上調用max_size()
來確定std::string
的最大大小。詳情請參閱max_size()。
max_size()不是我很感興趣的,capacity()更相關。 –
有標準沒有定義默認容量。 – Galik
你遇到的錯誤不是因爲字符串有'默認容量',這是因爲你在隨機存儲器周圍。 – pvg
@Galik當你做line.capacity()時,它會返回22,但是肯定會發生更多的事情發生在這裏 –