我使用Ms 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替换set(调整大小为100000),则输出将是相同的,但在任务管理器中我看到~3,400Mb。
为什么是3 Mb?
抱歉我的英语不好,请提前告知你。
答案 0 :(得分:1)
评论中已回答了设置大小和其他内存使用情况。
矢量使用的计算量小于4.1MB,因为visual studio的std :: string会将小字符串存储在字符串内部的缓冲区中。如果字符串大于缓冲区,则它将分配动态缓冲区来存储字符串。
这意味着str.capacity() + sizeof(string)
对于小于缓冲区大小的值(在您的情况下是所有字符串,因为Visual C&C的缓冲区恰好是16个字节)不正确。
尝试在字符串中使用更大的值运行它。例如添加常量字符串&#34; 12345678901234567890&#34;将每个值放到向量之前,你的内存使用量应该超过200k(20 * 10,000)的额外数据,因为字符串必须开始分配动态缓冲区。
答案 1 :(得分:0)
当您将项目放入集合时,不仅项目本身会占用空间,还会设置内部簿记。 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&);
};
如您所见,value只是节点的一部分。在我的PC上,sizeof(string)在编译为32位可执行文件时为28个字节,树节点的大小为44个字节。