簡體   English   中英

Qt5的內存問題

[英]Memory issues with Qt5

我正在編寫一個應用程序,其中我從一個csv文件中讀取值。 每行被分隔,逗號存儲在矢量中。 每行有4個值。 然后,我將每個值存儲到另一個向量。 csv文件有5.795.857行。 所以在我的結構中,我想存儲4 * 5.795.857值。 問題在於應用程序崩潰了。 正如我在調試器中看到的那樣,我大約在405.000行處崩潰。 我知道我的計算機有些舊,但是我認為它應該能夠存儲此數量的值。 我在WindowsXP 32bit上運行Qt5,我有1GB內存。

我是Qt和C ++編程的新手,但是當我遇到此類問題時,作為Java開發人員,我會增加堆大小。 你以為這是我的問題嗎? 如果是,我如何增加Qt5的堆大小?

這是我的代碼,它讀取文件並將其存儲在數據結構中

std::vector  < std::vector < QString> >  Server::loadCsvFile( const char* path )
{
  vector <QString> temp;
  vector  <vector <QString> > dataFlow;
  string dataString;
  QString row;
  ifstream dataFile( path );

  int stopCounter = 0;

  //while((dataFile.good()) && (stopCounter < 1095))
  while (dataFile.good())
  {
    stopCounter++;
    getline( dataFile, dataString );
    row = QString::fromStdString( dataString );
    //cout << "counter: " << stopCounter << "\n";
    QStringList rowList = row.split( "," );

    for(  int i=0; i < rowList.size(); i++ )
    {
      temp.push_back( rowList.at(i));
    }

    dataFlow.push_back( temp );
    temp.clear();
    rowList.clear();
  }

  dataFile.close();
  dataFlow.pop_back();

  return dataFlow;
}

到現在為止,我進行了一些更改,以查看是否可以解決我的問題,但是什么也沒有。 這是我的代碼知道的樣子:

std::vector < QStringList > Server::loadCsvFile2( const char* path )
{
    std::vector < QStringList > dataFlow;
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        throw std::runtime_error("Can't open the file " +
                                 std::string(path));
    QTextStream in(&file);
    int counter = 0;
    while (!in.atEnd())
    {
        counter++;
        dataFlow.emplace_back(in.readLine().split(","));
        cout << counter << "\n";
    }
    return dataFlow;
}

基本上, std::vector包含三個元素:

  • 大小
  • 元素數組
  • 能力

容量是向量當前可以容納的元素數,它是陣列的實際大小(在RAM中)。 大小是向量中實際包含的元素數。 例如,當您創建一個空的vector<int> ,其大小為0,容量為10(或其他我不知道的值),並且該數組消耗10 * sizeof(int) 如果push_back一個值,則大小為1,但容量或數組的實際大小未更改。

但是,當向量中有10個元素並嘗試添加一個元素時,會發生某種情況:實際數組已滿( vec.size() == vec.capacity() ),因此算法必須擴展該容量:

  • 價值翻倍
  • 分配一個實際大小為新容量的新數組; 換句話說,分配20 * sizeof(int)個字節,
  • 將舊數組的內容復制到新數組,
  • 舊陣列消耗的可用內存,
  • 現在,因為有可用空間,所以像往常一樣添加該項目。

當然,您現在最多可以添加20個項目,添加21st將使算法分配40個項目,添加41st將使其分配80個項目,等等。

通常,您並不真正在乎這些內部細節。 但是,當您向向量添加很多項目時,事情就會開始出現問題。 向量增長得越多,更多的新分配和副本就花費更多時間並消耗RAM。 在您的情況下,我懷疑您的第405 001行使該算法需要分配810 000個元素,並從第一個元素復制到第二個元素,並且由於RAM運行速度非常低,因此您的操作系統正在將部分內容寫入磁盤,這已經死了慢。

您希望陣列的初始容量足夠大,以減少重新分配的發生。 您可以做的就是調用reserve方法,並為其提供足夠大的數量,以避免過多的分配。 但是,恐怕您可能沒有足夠的RAM來完成該過程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM