C++ 读取大型txt文件时在结构中动态分配向量

C++ 读取大型txt文件时在结构中动态分配向量,c++,memory,vector,dynamic,memcpy,C++,Memory,Vector,Dynamic,Memcpy,我目前正在学习C++语言,需要读取一个包含5000多个双类型数字的文件。由于push_back将在分配新数据时生成一个副本,因此我试图找到一种减少计算工作量的方法。请注意,该文件可能包含随机数目的双重类型,因此通过指定足够大的向量来分配内存并不是解决方案 我的想法是快速读取整个文件并获得数组的大小和近似值。在里面发现了一个有趣的想法,可以在下面的代码中找到 基本上,包含文件数据的向量插入到名为PathStruct的结构类型中。请记住,PathStruct包含的内容比这个向量多,但为了简单起见,我

我目前正在学习C++语言,需要读取一个包含5000多个双类型数字的文件。由于push_back将在分配新数据时生成一个副本,因此我试图找到一种减少计算工作量的方法。请注意,该文件可能包含随机数目的双重类型,因此通过指定足够大的向量来分配内存并不是解决方案

我的想法是快速读取整个文件并获得数组的大小和近似值。在里面发现了一个有趣的想法,可以在下面的代码中找到

基本上,包含文件数据的向量插入到名为PathStruct的结构类型中。请记住,PathStruct包含的内容比这个向量多,但为了简单起见,我删除了所有其他内容。函数接收PathStruct指针的引用并读取文件

结构路径结构 { std::向量平凡向量; }; bool getFileContentPathStruct*&路径 { std::ifstream filenamesimplePath.txt,std::ios::in | std::ifstream::binary; 如果!filename.good 返回false; std::向量缓冲区{}; std::istreambuf_迭代器iterfilename; std::istreambuf_迭代器end{}; 标准::复制器,结束,标准::背面插入器缓冲; 路径->平凡向量.reservebuffer.size/sizeofdouble; memcpy&path->平凡向量[0],&buffer[0],buffer.size; 返回true; }; int main argc,字符**argv { PathStruct*path=新的PathStruct; const int result=getFileContentpath; 返回0; } 当我运行代码时,编译器给出以下错误:

损坏的大小与上一个大小,已中止的内核转储


我认为我的问题在于指针使用不当。这肯定不是我的强项,但我找不到问题所在。我希望有人能帮助这个可怜的灵魂。

如果您的文件只包含连续的双精度值,您可以检查文件大小并将其除以双精度值。来确定您可以使用的文件大小,但是这个函数可以从C++ 17中获得。如果不能使用C++ 17,则可以找到其他方法来确定文件大小< /p> 或使用指针:

auto numberOfValues = fileSize / sizeof(double);
std::vector<double> values(numberOfValues);
// Notice that I pass numberOfValues * sizeof(double) as a number of bytes to read instead of fileSize
// because the fileSize may be not divisable by sizeof(double)
inputFile.read(reinterpret_cast<char*>(values.data()), numberOfValues * sizeof(double));
可供替代的 如果可以修改文件结构,则可以在文件开头添加多个双精度值,并在读取双精度值之前读取此数字。这样,您将始终知道要读取的值的数量,而无需检查文件大小

备选案文2 您还可以将容器从std::vector更改为。这个容器类似于std::vector,但它没有为数据保留单个缓冲区,而是具有更小的数组。如果插入数据且阵列已满,则将分配并链接附加阵列,而不复制以前的数据。
然而,这代价很小,数据访问需要两个指针解引用,而不是一个指针解引用

您知道该文件将拥有最少的数据量吗?仅仅通过查看代码来分配两个向量是没有意义的,这似乎只是浪费资源。此外,我认为一个关键点是你的替身是如何在文件中编码的。以二进制形式?具有固定长度的ASCII/文本表示法?etc5000 double占用了惊人的40kB内存,我只需要保留一个合理的最大大小,并使用push_back,保持简单。如果你发现速度很慢,那就是开始优化的时候了。你的代码的问题是调用reserve而不是resize,这意味着向量仍然是空的,因此你不允许写入。txt后缀通常与文本一起使用。
auto numberOfValues = fileSize / sizeof(double);
std::vector<double> values(numberOfValues);
// Notice that I pass numberOfValues * sizeof(double) as a number of bytes to read instead of fileSize
// because the fileSize may be not divisable by sizeof(double)
inputFile.read(reinterpret_cast<char*>(values.data()), numberOfValues * sizeof(double));