2016-04-21 267 views
1

我必须读取Qt中最大3 GB的非常大的文本文件,并将它们存储为一组行。 (稍后与它们一起使用) 我知道这些行具有非常相似的大小,所以我在计算可能的行数并在读取文件之前调整向量大小。但是我仍然在大约3.000.000行或者大约916MB存储RAM中得到bad_alloc。 在程序崩溃的时候,没有一个push_back被调用,因为在136 MB的文件中,我的代码将该向量的大小调整为> 7.000.000。std :: vector bad_alloc不使用push_back

我正在运行带有8 GB RAM的Windows 10 x64,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. 

编辑: 我只是想出一些东西。我(必须)使用QML,并且我的QML创建读取文件的类实例。如果我在不加载.qml文件的情况下从main方法读取文件,则不会发生bad_alloc错误。如果我加载qml并读取文件,qt表示没有足够的内存来加载qml库。

编辑2: 因此,如果没有QML,会发生崩溃,出现在8.000.000行和1.5 GB保留空间。

编辑3: 我更新了上面的代码到当前状态。

+0

要清楚:while()在cnt =〜3000000时的bad_alloc occours。 – hisMajesty

+0

我不认为你需要'调整大小',这使得大小开始的向量。您可能需要['reserve'](http://www.cplusplus.com/reference/vector/vector/reserve/),这会增加容量,而不会将空白项目推入矢量中。 – Petesh

+0

我在调整大小之前尝试了保留。保留代码在2.000.000行崩溃。我也尝试过保留,然后调整大小,我仍然停留在3.000.000行。 – hisMajesty

回答

2
result.resize(size); 

我想你想reserve(size)那里,resize()做的push_back -ing size空字符串相当于....

此外,请记住,在vector只是保持固定大小的QString字符串管理对象:它们可能包含指针,当实际文本分配给它们时,它们将动态分配内存来存储该文本。这很可能是您的bad_alloc来自哪里。在in.readLine();之内必须预期这种分配。

你或许应该摆脱这种...

result.shrink_to_fit(); 

...作为一种实现可能会试图将字符串从现有的缓冲区复制到一个准确,只有足够大,并且在这样做暂时需要更多的记忆。

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

+0

你说得对,预留蚂蚁不要使用shrink_to_fit是更好的代码。但是这个dosn't解决了这个问题。我用新信息编辑了我的帖子。 – hisMajesty

相关问题