2016-04-21 107 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

相關問題