istringstream() (possibly) memory leak



假设你想从大文本文件(~300mb)读取数据到向量数组:vector<string> *Data(假设列数是已知的)。

//file is opened with ifstream; initial value of s is set up, etc...

Data = new vector<string>[col];
string u;
int i = 0;
do
{       
    istringstream iLine = istringstream(s);
    i=0;
    while(iLine >> u)
    {
        Data[i].push_back(u);
        i++;
    }
}
while(getline(file, s));

此代码适用于小文件 (<50mb),但在读取大文件时内存使用量呈指数级增长。我很确定问题在于每次在循环中创建istringstream对象。然而,在两个循环之外定义istringstream iLine;并通过iLine.str(s);将每个字符串放入流中,并在内部 while-循环 (iLine.str(""); iLine.clear(); ) 之后清除流,也会导致相同的内存爆炸顺序。出现的问题:

  1. 为什么istringstream会这样行事;
  2. 如果是预期行为,如何完成上述任务?

谢谢

编辑:关于第一个答案,我确实清理了代码后面数组分配的内存:

for(long i=0;i<col;i++)
    Data[i].clear();
delete []Data;

完整的编译就绪代码(添加标头):

int _tmain(int argc, _TCHAR* argv[])
{
ofstream testfile;
testfile.open("testdata.txt");
srand(time(NULL));
for(int i = 1; i<1000000; i++)
{
    for(int j=1; j<100; j++)
    {
        testfile << rand()%100 << " ";
    }
    testfile << endl;
}
testfile.close();
vector<string> *Data;
clock_t begin = clock();
ifstream file("testdata.txt"); 
string s;
getline(file,s);
istringstream iss = istringstream(s);
string nums;
int col=0;
while(iss >> nums)
{
    col++;
}
cout << "Columns #: " << col << endl;
Data = new vector<string>[col];
string u;
int i = 0;
do
{
    istringstream iLine = istringstream(s);
    i=0;
    while(iLine >> u)
    {
        Data[i].push_back(u);
        i++;
    }
}
while(getline(file, s));
cout << "Rows #: " << Data[0].size() << endl;
for(long i=0;i<col;i++)
        Data[i].clear();
    delete []Data;
clock_t end = clock();
double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
cout << elapsed_secs << endl;
getchar();
return 0;
}
vector<>内存

呈几何增长。一个典型的模式是,每当需要增长时,它都会将容量翻倍。如果您的循环在这样的阈值之后立即结束,这可能会留下大量分配但未使用的额外空间。完成后,您可以尝试在每个向量上调用shrink_to_fit()

此外,由C++分配器(甚至普通malloc())分配的内存通常不会返回到操作系统,而是留在进程内部可用内存池中。 这可能会导致进一步的明显增长。它可能会导致shrink_to_fit()的结果从过程外部不可见。

最后,如果您有很多小字符串("2 位数字"),则string对象的开销可能相当大。 即使实现使用小字符串优化,我也会假设一个典型的字符串使用不少于16或24字节(大小,容量,数据指针或小字符串缓冲区) - 在size_type为64位的平台上可能更多。对于 3 字节的有效负载来说,这是大量的内存。

所以我假设你看到了vector<>的正常行为

我严重怀疑这不是 istringstream 问题(特别是,鉴于您在循环外与 iLine 构造函数有相同的结果)。

这可能是 std::vector 的正常行为。 为了测试这一点,你运行完全相同的行怎么样,但注释掉:Data[i].push_back(u); .看看你的记忆力是否以这种方式增长。如果没有,那么您就知道问题出在哪里。

根据您的库,vector::p ush_back每次需要更多空间时都会将其容量扩展1.5(Microsoft)或2(glib)。

相关内容

  • 没有找到相关文章

最新更新