我正在编写一个应用程序,其中我从csv文件读取值。每一行被分隔,逗号被存储在一个向量中。每一行有4个值。然后我将每个值存储到另一个向量中。csv文件共有5.795.857行。所以在我的结构中,我想存储4*5.795.857个值。问题是应用程序会崩溃。正如我在调试器中看到的,它大约在405,000行处崩溃。我知道我的电脑有点旧了,但我认为它应该能够存储这么多的值。我在WindowsXP 32位上运行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
a值,则大小为1,但容量或数组的实际大小没有变化。
但是当你的向量中有10个元素并试图添加一个元素时,会发生一些事情:实际数组已满(vec.size() == vec.capacity()
),因此算法必须扩展该容量:
- 容量值的两倍,
- 分配一个实际大小为新容量的新数组;换句话说,分配
20 * sizeof(int)
字节, - 将旧数组的内容复制到新数组中,
- 旧数组占用的空闲内存,
- 现在,像往常一样添加项目,因为有房间可用。
当然,你现在可以添加最多20项,添加第21项将使算法分配40项,添加第41项将使算法分配80项,等等。
通常,你并不真正关心这些内部细节。但是当你向一个向量中加入很多很多的元素时,事情就开始有问题了。向量增长得越多,新的分配和拷贝所花费的时间和消耗的RAM就越多。在您的情况下,我怀疑您的405 001行使算法需要分配810,000个元素,并从第一个复制到第二个,并且由于RAM运行非常低,您的操作系统正在将其部分写入磁盘,这是死慢。
您希望数组的初始容量足够大,以减少重新分配的发生。你能做的是调用reserve
方法,并给它一个足够大的数字,以避免太多的分配。然而,我担心你可能没有足够的内存来实现这个过程,即使这样。