C++ 在C+中创建一个包含由换行符分隔的单词和这些单词的字符串向量的文件+;有同样大小的吗?

C++ 在C+中创建一个包含由换行符分隔的单词和这些单词的字符串向量的文件+;有同样大小的吗?,c++,arrays,c++11,vector,sizeof,C++,Arrays,C++11,Vector,Sizeof,该文件的格式如下: 单词1 单词2 单词3 在从文件中读取这些单词后,我创建了字符串向量,如下所示: std::vector<string> words; string w; ifstream file("input"); while(getline(file,w)) words.push_back(w); file.close(); std::向量词; 字符串w; ifstream文件(“输入”); while(getline(文件,w)) 字。推回(w); file.

该文件的格式如下:

单词1
单词2
单词3

在从文件中读取这些单词后,我创建了字符串向量,如下所示:

std::vector<string> words;
string w;
ifstream file("input");
while(getline(file,w))
    words.push_back(w);
file.close();
std::向量词;
字符串w;
ifstream文件(“输入”);
while(getline(文件,w))
字。推回(w);
file.close();

向量占用的物理内存大小是否与输入文件的大小相同?为什么?

向量实现有两个内存占用:sizeof(vector)是堆栈上使用的内存(通常为24字节),然后是动态分配的内存,第一个是由
向量
分配,第二个是由
字符串
参数分配

向量可能会分配比它实际需要的更多的内存来容纳所有字符串:如果您通过
向后推
(或
向后放置
)来增加它的容量,那么每当它耗尽容量时,它就会将动态分配的内存增加一倍

最后,字符串有自己的开销:对于短单词(小于
sizeof(string)
),字符串中未使用的内存会被浪费,而对于长单词,字符串必须分配动态内存并保留单独的指针(导致内存开销)

因此,答案是:
向量
占用更多空间(可能分布在堆栈和堆上的不同位置之间)

向量占用的物理内存大小是否与输入文件的大小相同

这取决于“向量占用的物理内存大小”的含义。向量对象本身的大小通常是3个指针(或1个指针和2个数字)的大小,例如64位体系结构上的24个字节。然而,该向量随后至少动态地为N个字符串对象分配空间,其中N是文件行数。请注意,如果不保留向量空间,则可能会为N个字符串分配更多的空间

每个字符串对象都有一些“内部”大小(在我的实验中,libc++/Clang为24字节,libstdc++/GCC为32字节)

然后,每个字符串都需要存储文本行。它可能会动态分配内存,或者对于短字符串,它可能会采用小字符串优化。对于动态内存分配,您需要考虑一些填充,因为动态分配的缓冲区是对齐的(在我的环境中为16字节)

因此,您无法轻松比较此处的内存占用情况。但是,一般来说,字符串向量会有很多开销



如果要避免这种开销,只需将整个文件内容读入单个字符数组(vector、string),然后创建一个附加数组,其中包含指向各行开始位置的指针。

需要考虑的事项:实际的
std::vector
对象本身需要空间;
std::string
对象本身需要空间;
std::getline
读取的行不包括换行符。字符串视图的向量可能比字符视图的向量更合适