大きなテキスト ファイル (~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-loop ( iLine.str(""); iLine.clear();
) の後でストリームをクリアすると、同じ順序でメモリ爆発が発生します。発生する質問:
- なぜ
istringstream
このように振る舞うか; - それが意図した動作である場合、上記のタスクをどのように達成できますか?
ありがとうございました
編集:最初の答えに関しては、コードの後半で配列によって割り当てられたメモリをクリーンアップします:
for(long i=0;i<col;i++)
Data[i].clear();
delete []Data;
FULL COMPILE-READY CODE (ヘッダーを追加):
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;
}