2015-09-21 109 views
4

當我在類中創建一個std::string成員變量時,在實例化時是否已經分配了默認內存?或std::string推遲分配,直到它實際使用?什麼時候在初始化時發生std :: string分配

我使用Visual Studio 2010的那一刻,我注意到,當我創建一個空字符串:

std::string s0; 
    std::string s1 = ""; 

兩個有能力== 15集。那麼這是否意味着它已經分配了15個字節的內存?如果是的話,我可以防止這種情況導致沒有內存分配?

這是不同的編譯器的具體實現嗎?

+0

請注意,觀察到的行爲中沒有任何內容表明小字符串優化正在發生。 – juanchopanza

+0

_「如果是的話,我可以防止這種情況導致沒有內存分配嗎?」_爲什麼? –

+0

因爲我必須緩存結構的LOTS以及診斷字符串,並且我不想通過分配更多的內存來浪費內存。另一種方法是根據需要動態分配字符串。 – Devolus

回答

1

注意:這個答案是錯誤的,但是stackoverflow不接受刪除接受的答案。

原來的答覆:

你看到的是SSO(小字符串優化)的做法。這確實是具體實施。

查看this answer瞭解更多詳情。

+0

我現在調試它,它似乎真的在此實現中調用malloc。感謝您的鏈接。 – Devolus

+2

我不認爲在OP的帖子中有任何建議他們看到SSO。在不使用SSO的實現中,可以觀察到相同的結果。 – juanchopanza

+0

要清楚,答案是不正確的。 – juanchopanza

4

空的std::string的初始容量未由標準指定,並且取決於實施。

許多實現將分配約16個左右的字符(是的,容量是指分配的內存)的初始容量。

+0

呵呵,爲什麼?奇怪的。我的意思是我得到了他們希望字符串最終會添加字符的功能,但爲什麼不推遲分配直到真的需要它?如果是這樣,你知道,不是......?也許他們認爲,在確保大量初始分配的情況下,在構造函數中進行分配的性能要高於在每個擴展中運行「if(容量== 0)」的性能。 –

+1

@LightnessRacesinOrbit:通常它是在SSO的上下文中進行(參考文獻[ANORM的回答(http://stackoverflow.com/a/32695592/822669)。),就是這種情況例如。在從VS 2010開始的VS中,以及從g ++ 5.1開始的g ++(一個很好的閱讀:http://info.prelert.com/blog/cpp-stdstring-implementations)。即。一個16字節左右的小緩衝區是std :: string對象的一部分,避免了爲小字符串分配動態內存,但是當字符串變大時會增加一些開銷。這是一種折衷方案,可以提高某些工作負載下的性能,但會在其他方面下降。 –

+0

@LightnessRacesinOrbit查看我的答案,它可能是分配是用於迭代器驗證的代理對象(並且SSO是容量== 15的原因),它不會存在於零售/發佈版本中。 –

0

編譯器決定需要爲該字符串初始化多少內存。不同的編譯器會分配不同數量的內存將是常用的句子。

+4

不是編譯器。標準的庫實現。 –

2

我沒有訪問VS2010,但VS2012已經嘗試這樣做,我看到的正是你描述相同的行爲(容量15,被分配一些內存)

正在發生的事情(特別是在這種情況下, )是Small String Optimization給你的容量爲15.沒有內存被分配給這個。

但是,MS的C++標準庫也有額外的調試檢查,有時必須在結構中存儲額外的信息,以便他們可以在運行時對諸如迭代器驗證之類的東西運行額外的檢查。您正在看到正在創建的那些「代理」對象之一。在剛剛運行的默認版本構建中的VS的最新版本將關閉這些檢查。但是,如果內存提供服務,在較舊版本的Visual Studio中關閉它們更加痛苦 - 請參閱_ITERATOR_DEBUG_LEVEL error in visual studio以及其他相關答案以瞭解如何關閉它們。這可能是因爲你在2010年只需要一個'Release'版本,另外你可能需要解決'_ITERATOR_DEBUG_LEVEL'和'_SECURE_SCL'定義。

相關問題