C++ std::矢量错误分配,不使用推回

C++ std::矢量错误分配,不使用推回,c++,qt,vector,stdvector,bad-alloc,C++,Qt,Vector,Stdvector,Bad Alloc,我必须在Qt中读取非常大的文本文件,高达3 GB,并将它们存储为行集合。(稍后与他们合作) 我知道这些行的大小非常相似,所以在读取文件之前,我计算了可能的行数并调整了向量的大小。但是我仍然得到一个坏的配置,大约有3.000.000行或~916 MB的备用RAM。 在程序崩溃时,没有一个push_返回调用的位置,因为在136 MB的文件中,我的代码将向量调整为>7.000.000 我正在运行Windows10x64和8GB内存,4,9是免费的 这是我的尝试: QString filepath =

我必须在Qt中读取非常大的文本文件,高达3 GB,并将它们存储为行集合。(稍后与他们合作) 我知道这些行的大小非常相似,所以在读取文件之前,我计算了可能的行数并调整了向量的大小。但是我仍然得到一个坏的配置,大约有3.000.000行或~916 MB的备用RAM。 在程序崩溃时,没有一个push_返回调用的位置,因为在136 MB的文件中,我的代码将向量调整为>7.000.000

我正在运行Windows10x64和8GB内存,4,9是免费的

这是我的尝试:

QString filepath = "K://_test//test.txt";
QFile qfile(filepath)

if (!qfile.open(QIODevice::ReadOnly | QIODevice::Text)) {
   return false;
}

// All lines have similar size, so try to calculate the amount from filesize
QFileInfo info(qfile);
long size = info.size() / 1024; // in kb

size = size / 0.0453333; // Cutting decimals is ok at this amount

std::vector<QString> result;

if (size > 0) {
   // Replaced: result.resize(size);
   result.reserve(size);
}

//Reading
QTextStream in(&qfile);
QString line = "";
long cnt = 0;

while (!in.atEnd()) {
   line = in.readLine();

   if (line.isEmpty() == false)
   {
      result.push_back(line);

      /**Replaced:
      if (cnt > (size - 1)) {
         result.push_back(line);
      }
      else {
         result.at(cnt) = line;
      }*/

      cnt++;
   }
}

// Removed: result.shrink_to_fit();

file->setLines(result);
// file is a object with only the filepath and the lines in it.
QString filepath=“K://\u test//test.txt”;
QFile QFile(文件路径)
如果(!qfile.open(QIODevice::ReadOnly | QIODevice::Text)){
返回false;
}
//所有行都有相似的大小,所以请尝试根据filesize计算数量
QFileInfo信息(qfile);
long size=info.size()/1024;//以kb为单位
尺寸=尺寸/0.0453333;//在这个数量上减少小数是可以的
std::向量结果;
如果(大小>0){
//替换:结果。调整大小(大小);
结果:储备量(大小);
}
//阅读
QTextStream-in(&qfile);
QString line=“”;
长cnt=0;
而(!in.atEnd()){
line=in.readLine();
if(line.isEmpty()==false)
{
结果:推回(线);
/**取代:
如果(cnt>(尺寸-1)){
结果:推回(线);
}
否则{
结果:at(cnt)=直线;
}*/
cnt++;
}
}
//移除:结果。将_收缩到_配合();
文件->设置行(结果);
//文件是一个仅包含文件路径和其中的行的对象。
编辑: 我刚想出来一件事。我(必须)使用QML,并且我的QML创建读取文件的类实例。如果我在不加载.qml文件的情况下从main方法读取该文件,则不会出现错误。如果我加载qml并读取文件,qt会说没有足够的内存来加载qml库

编辑2: 因此,如果没有QML,崩溃occours将以8.000.000行和1.5 GB的保留空间出现

编辑3: 我将上面的代码更新为当前状态

   result.resize(size);
我想您应该
在那里保留(大小)
,因为
resize()
相当于
向后推
-ing
大小
空字符串

此外,请记住,
向量
只保存固定大小的
QString
字符串管理对象:它们可能包含指针,当实际文本分配给它们时,它们将动态分配内存来存储该文本。这很可能就是您的
错误分配的来源。此类分配必须在.readLine()中的
中进行

你可能应该把这个处理掉

result.shrink_to_fit();
…作为一个实现,可能会尝试将字符串从现有缓冲区复制到一个足够大的缓冲区,这样做会暂时需要更多内存


如果您想以极低的开销在内存中保留大量文本,我建议您对文件进行内存映射。如果对你有用的话,你可以保留一个指向每行第一个字符的
向量

要清楚的是:在cnt=~3000000处的while()中的bad_alloc occours。我认为你不需要
resize
这使得向量的大小开始。您可能需要,这会增加容量,而不会将空白项推入向量。我在调整大小之前尝试了保留。使用reserve时,代码崩溃为2.000.000行。我还尝试了reserve,然后是resize,我仍然停留在3.000.000行。你是对的,reserve ant不使用shrink-to-fit是更好的代码。但这并不能解决问题。我用新信息编辑了我的文章。