C++ 这种方法是否会涉及内存重新分配,从而影响其效率?

C++ 这种方法是否会涉及内存重新分配,从而影响其效率?,c++,file,vector,ifstream,C++,File,Vector,Ifstream,我发现我们可以将文件的内容读入std::vector,如下所示: ifstream fin(..., ios::in); std::vector<char> buf( std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>()); 这个方法会有同样的内存重新分配问题吗?是一个输入迭代器,所以开始和结束之间的距离事

我发现我们可以将文件的内容读入std::vector,如下所示:

  ifstream fin(..., ios::in);
    std::vector<char> buf(
            std::istreambuf_iterator<char>(fin), 
            std::istreambuf_iterator<char>());   
这个方法会有同样的内存重新分配问题吗?

是一个输入迭代器,所以开始和结束之间的距离事先不知道。除非文件非常小,否则在构造过程中会进行多次重新分配。对于随机访问迭代器,距离是已知的,在这种情况下,构造函数可以避免额外的内存分配

如果您大致知道文件的大小,则可以在读取之前使用:

std::vector<char> buf;
buf.reserve(file_size);
buf.insert(buf.end(), std::istreambuf_iterator<char>(fin), 
        std::istreambuf_iterator<char>());   
std::vector buf;
基本储备(文件大小);
buf.insert(buf.end(),std::istreambuf_迭代器(fin),
std::istreambuf_迭代器();

Vector保持按顺序分配的数据。 添加新元素时,在最后一个元素之后可能没有可用内存,然后需要将所有数据移动到内存中有足够空间容纳新旧数据的位置

最好的解决方案是使用以下命令为vector提供一个缓冲区:vector::reserve(size)

您的代码可以是:

std::vector<char> buf;
buf.reserve(10000);
buf.assign(std::istreambuf_iterator<char>(fin),
            std::istreambuf_iterator<char>());
buf.shrink_to_fit(); //free the unused memory
std::vector buf;
基本储备(10000);
赋值(std::istreambuf_迭代器(fin),
std::istreambuf_迭代器();
buf.收缩到合适的位置()//释放未使用的内存

与IO时间相比,重新分配所花费的时间将不算什么。读取文件大小,保留那么多空间,然后重新读取vector将使其效率低下。与IO中花费的时间相比,重新分配的时间可以忽略不计。特别是当输入文件很大时,因为
seekg
必须检查整个文件才能获得大小。@WiseBro重新分配N字节而不是M字节涉及分配N字节,复制所有信息,然后取消分配旧存储。使用大的数字是无效的。如果保留是一个问题,那么可以使用无需重新分配的存储,例如预定义块的列表。@Swift FridayPie让我们简化一下。假设n字节的时间,memcpy取n个单位。重新定位时的总时间=
N+N/2+N/4…
=
2*N
。假设OP有一个nvme ssd。即使这样,从内存中传输的数据也超过10x ~
10N
。读两遍=
20*N
。这是最好情况下(假设我的计算是正确的)差异的10倍。@theWiseBro这就是为什么在任何现代文件系统中,你不需要阅读文件就可以知道它的大小,哈哈。因此,您最好设计文件格式,以便在头中存储精确大小的数据和偏移量。如果文件有10个字符,这不是非常有效。这与已提供的答案基本相同。。。顺便说一下,
std::vector::shrink_to_fit()
可能会重新分配整个向量。我不确定是否值得在这里冒险。@Fareanor也一样。关于vector::shrink_to_fit,在网站cppreference.com和cplusplus.com上说它只是“将容量减少到vector::size”。释放内存时无法重新分配。@idclev您可以使用istream::tellg()方法读取文件大小,而使用文本值。看看这里:codeshrains.com/2018/02/02/how-to-find-size-of-file-in-c。然后vector::将文件收缩到合适的文件是不必要的,但如果您得到一个大文件,它将不会有效率。您需要选择更适合您的程序的方法。减少容量意味着重新分配。文件中明确了这一点:
std::vector<char> buf;
buf.reserve(10000);
buf.assign(std::istreambuf_iterator<char>(fin),
            std::istreambuf_iterator<char>());
buf.shrink_to_fit(); //free the unused memory