如何直接将大量内存读入std :: vector?

kfm*_*e04 7 c++ placement-new c++11

我有一个巨大的连续数组x,我fread来自一个文件.

如何将这个块放入std::vector<>?换句话说,我更喜欢将结果std::vector<>放在数组而不是数组中,但我希望生成的C++代码与这个将Cunk版本直接放入数组的普通C版本一样高效.

通过搜索,我想我可能不得不以某种形式使用placement-new,但我不确定调用和所有权问题的顺序.另外,我是否需要担心对齐问题?

我正在测试T = unsigned,但我希望有一个合理的解决方案适用于任何POD结构.

using T = unsigned;
FILE* fp = fopen( outfile.c_str(), "r" );
T* x = new T[big_n];
fread( x, sizeof(T), big_n, fp );

// how do I get x into std::vector<T> v
// without calling a gazillion push_backs() or copies ?!?

delete[] x;
fclose( fp );
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 10

您使用std::vector 构造函数来设置向量的大小,并用于std::vector::data获取指向已分配内存的指针.

保持使用fread:

std::vector<T> x(big_n);
fread(x.data(), sizeof(T), big_n, fp);
Run Code Online (Sandbox Code Playgroud)

正如其他人所指出的那样,fread如果类型T不是POD类型,那么很可能不会起作用.然后,您可以使用C++流并将std::istreambuf_iterator文件读入向量.然而,它的缺点是它遍历文件中的所有项目,如果big_n它听起来那么大,那么这可能是性能问题.


但是,如果文件真的很大,我宁愿建议使用内存映射来读取文件.

  • @jrok如果T不是字符类型,你就不能用`fread`可靠地读它.如果T不是POD,几乎可以肯定你无法阅读它. (5认同)
  • 这是一个简单的解决方案,但并不像"普通C版本那样高效",因为它使用零值初始化向量. (2认同)
  • @ kfmfe04`std :: sort`也可以对普通的原始数组进行排序,这就是`mmap`返回的内存指针可以看作. (2认同)