簡體   English   中英

的std ::設為 <string> 和記憶

[英]std::set<string> and memory

我使用Visual Studio2010 Express女士並擁有下一個代碼

set<string> res;
for(uint x = 0; x<100000;++x) res.insert( vtos(x,0) );
uint size1=0;uint size2=0;uint size3=0;
set<string>::const_iterator it=res.begin();
for(;it!=res.end();++it){
    string str = *it;
    size1+=str.size();
    size2+=str.capacity();
    size3+=str.capacity() + sizeof(string);
}
cout << "size1 == " << ((float)size1)/1024/1024 << endl;
cout << "size2 == " << ((float)size2)/1024/1024 << endl;
cout << "size3 == " << ((float)size3)/1024/1024 << endl;
while(true){}

的輸出是

size1 == 0.466242
size2 == 1.43051
size3 == 4.1008

周期(最后,這是一件壞事,我知道)僅用於觀看TaskManager。 在TaskManager中,我看到應用程序的內存為6,11 Mb

為什么是6M? 〜2Mb在哪里?

如果我將其替換為vector(大小調整為100000),則輸出將是相同的,但是在任務管理器中,我看到的是〜3,45Mb。

為什么是3 Mb?

對不起,我的英語不好,請提前解決。

注釋中已回答了設置的大小和其他內存使用情況。

由於Visual Studio的std :: string會將小字符串存儲在字符串內部的緩沖區中,因此該向量使用的內存少於4.1MB。 如果字符串大於緩沖區,它將分配一個動態緩沖區來存儲該字符串。 這意味着str.capacity() + sizeof(string)對於小於該緩沖區大小的值是不正確的(這是您的所有字符串,因為Visual C的緩沖區恰好是16個字節)。

嘗試以更大的值在字符串中運行它。 例如,將常量字符串“ 12345678901234567890”添加到每個值之前,將其作為向量,您的內存使用量應該會增加200k(20 * 10,000)以上,以增加額外的數據,因為這些字符串將必須開始分配動態緩沖區。

將項目放到集合中時,不僅項目本身會占用空間,而且還會設置內部簿記。 std :: set通常實現為一棵紅黑樹,這意味着該集中的每個項目都有一個節點。 在MSVC上,節點如下所示:

template<class _Value_type,
class _Voidptr>
struct _Tree_node
{   // tree node
    _Voidptr _Left; // left subtree, or smallest element if head
    _Voidptr _Parent;   // parent, or root of tree if head
    _Voidptr _Right;    // right subtree, or largest element if head
    char _Color;    // _Red or _Black, _Black if head
    char _Isnil;    // true only if head (also nil) node
    _Value_type _Myval; // the stored value, unused if head

private:
    _Tree_node& operator=(const _Tree_node&);
};

如您所見,值只是節點的一部分。 在我的PC上,當編譯為32位可執行文件時,sizeof(string)為28個字節,樹節點的大小為44個字節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM