2015-10-14 108 views
4

我正在開發一個項目,我絕對需要在內存中有連續的數據。 我想存儲一些(最多100個)字符串(我不知道每個字符串的實際大小)。所以我會創建一個由100個元素組成的向量。如何在內存中存儲矢量<string>

std::vector<std::string> vect; 
vect.reserve(100) 

但是一個字符串可以是任意大小。那麼它是怎樣工作的?每當我更改一個字符串時,我的矢量是否會重新分配?或者是一個std :: string就像一個指向字符串第一個字符的指針,就像char *將用於C字符串一樣?

+0

http://stackoverflow.com/questions/1986966/does-s0-point-to-contiguous-characters-in-a-stdstring –

+2

'std :: string'的行爲就像你的例子中的一個指針。有一個小字符串優化,其中小字符串(小意味着〜20-40個字符)在'std :: string'本身內部。如果你需要所有的字符在連續的內存中,你將不得不使用'vector '並手動完成。 – nwp

+0

謝謝,那種信息是寶貴的,因爲字符串可以做背景的事情,這就是爲什麼我問這個。你說的是,它做了一些優化,可能會使它不連續? – FreeYourSoul

回答

7
  1. 每個stringstring類的一個實例和該實例將包含char*
  2. 向量中的string對象將在連續內存中。
  3. 每個string的字符將在連續的內存
  4. 所有所有字符串的字符不會在連續的內存,除非你定義一個自定義std::allocator的字符串
  5. 在字符串的內存位置可能當你增加的string
  6. 如果修改了vector將無法​​重新分配或Remo的大小,當你增加vector的大小或致電shrink_to_fit
  7. 位置在每個string的字符內存的變化可能會改變ve其中一個字符串
  8. 有一種叫做的小字符串優化。如果進場的每個string的字符將被存儲在string,而不是其他位置指向內通過char*
+0

所以一個字符串實際上只是一個字符的封裝* – FreeYourSoul

+0

它的模板,但如果你只使用默認的std :: string,那麼是的。 –

+1

@FreeYourSoul它有更多的東西,如容量和大小,而不僅僅是'char *'。 – nwp

2

std::vector的數據contiguosly佈局。但是std::string的實現並不能保證持有字符數組的內存本地存儲到類本身。它怎麼可能?就像你說的,你不知道弦會有多大。

很多陣列狀結構的具有佈局等如下:

class string 
{ 
    T * begin; 
    T * end; 
    T * capacity; 
} 

這意味着您100串的矢量將具有類佈局指向其中字符串被存儲在存儲器100個的實例。

現在,如果您需要儘可能緊密地打包內存分配,並且仍然想使用std::string,則可以編寫自定義allocator

也許你可以將字符串數據寫入char數組,並有第二個容器來存儲每個單獨的字符串+ NULL終止符的長度。

2

string的實現是實現定義的,並且實際上在某些編譯器的不同版本之間發生了變化(例如,從gcc 4.9到5.0)。即使您使用自定義分配器,也絕對不能保證連續string s在內存中連續存在,

所以如果你真的需要char s在內存中是連續的,你只能使用vector<char>