Я записал некоторые данные в файл следующим образом:
result = new QHash<QPair<int, int>, QVector<double> >;
QFile resfile("result.txt");
resfile.open(QIODevice::WriteOnly | QIODevice::Append);
QDataStream out(&resfile);
while(condition)
{
QString s=" something";
out<<s;
res->insert(QPair<int, int>(arange,trange),coeffs);
out<<res;
}
Файл закончился с равным 484 МБ.
После этого я прочитал это в цикле:
QString s;
QVector<QHash<QPair<int, int>, QVector <double> > > thickeness_result;
QFile resfile("result.txt");
resfile.open(QIODevice::ReadOnly);
QDataStream out(&resfile);
while (!out.atEnd())
{
thickeness_result.resize(thickeness_result.size()+1);
out>>s>>thickness_result.last();
}
Пока выполняется цикл чтения, я вижу, что в диспетчере задач моя программа начинает занимать около 1300 МБ памяти, и после этого я получаю сообщение об ошибке «In file text \ qharfbuzzng.cpp, строка 626: Недостаточно памяти».
Мой вопрос: это нормально, что программа начинает занимать более чем в 2 раза больше файловой памяти, и я должен читать ее порциями, или я делаю что-то не так?
ПРЕДУПРЕЖДЕНИЕ Все последующее предполагает, что QVector
ведет себя как std::vector
Да, это нормально. Происходит следующее: когда у вас есть 1024 элемента и вы хотите прочитать еще один, вызов resize
выделяет емкость для 2048 элементов, перемещает первые 1024 элемента и затем строит 1025-й элемент. Он уничтожает старый массив и возвращает память в кучу (но не в операционную систему). Затем, когда вы читаете 2049-й элемент, он делает все это снова, только на этот раз выделяя 4096 элементов. Куча состоит из 1024 элементов, но это бесполезно, если вы хотите 4096. Теперь у вас есть 1024, 2048 и 4096 элементов в куче (два из которых бесплатны и доступны для повторного использования).
Повторяйте, пока не прочитаете файл. Вы увидите, что в итоге вы получите примерно вдвое больший размер файла.
Первое правило — «не беспокойся об этом» — обычно это не проблема. Однако для вас это явно так.
Можете ли вы перейти на 64-битную программу? Это должно решить проблему.
Другой вариант — угадать, сколько элементов у вас есть (из размера файла) и вызвать .reserve
на вектор в начале.
Других решений пока нет …