2013-02-28 154 views
0

當我嘗試讀取大文件(〜412 MB)時,文件突然停止讀取。該計劃工作了一個月,但現在我有錯誤。我不知道爲什麼。你能幫忙嗎?當我檢查它使用淨化它說,該方案已內存分配文件讀取停止

s.write(block, f.gcount()); 

失敗我寫一個大文件到緩衝區(我讀文件的大件)。然後我解析這個緩衝區並讀取文件的下一部分。我試圖用較少的文件讀取文件,但結果是一樣的:程序剛剛停止閱讀,然後什麼都不做。沒有任何異常(我試圖抓住std :: exception) 是什麼原因?你能幫忙嗎?

該文件是非常簡單的:

p edge 45 45 

e 4 1 

e 5 6 

下面是代碼:

readFile(char name[]) { 
     ifstream f; 
     f.open(name,ifstream::binary); 
     char buffer[256], token[20]; 
     int i, j, k, tmp; 
     int vi = 0, vj = 0; 
     int num_edges = 0; 

     if (! f.is_open()) 
     { 
      cout << "Error opening file: " << name << endl; 
      //_getch(); 
     exit(1); 
     } 

     strstream s; 
     static const int N = 1024*1024; 
     char block[N]; 


    while (! f.eof()) 
    { 
     s.clear(); 
     f.read(block, N); 
     s.write(block, f.gcount()); 

     while (! s.eof()) 
     { 
      s.getline(buffer, 250); 
      if (s.eof()) 
      { 
       s.write(buffer, s.gcount()); 
       break; 
      } 

      if (buffer[0] == 'c') 
      { 
       continue; 
      } 

      if (buffer[0] == 'p') 
      { 
       cout << buffer << endl; 
       sscanf(&buffer[7], "%d", &globalColouredVertices.size); 

       if(globalColouredVertices.size > MAX_VERTICES) { 
        cout << "Too many vertices (> " << MAX_VERTICES << ")"<< endl; 
        exit(2); 
       } 

       //e.resize(globalColouredVertices.size); 
       for (i = 0; i < globalColouredVertices.size; i++) 
       { 
        globalColouredVertices.ele[i].point = i; 
       } 
      } 
      if (buffer[0] == 'e') 
      { 
       num_edges++; 
       i = 2; 
       j = 0; 
       while ((buffer[i] >= '0') && (buffer[i] <= '9')) 
       { 
        token[j++] = buffer[i]; 
        i++; 
       } 
       token[j] = '\0'; 
       vi = atoi(token); 
       i++; 
       j = 0; 
       while ((buffer[i] >= '0') && (buffer[i] <= '9')) 
       { 
        token[j++] = buffer[i]; 
        i++; 
       } 
       token[j] = '\0'; 
       vj = atoi(token); 
       vi--; 
       vj--; 
       e[vi][vj] = 1; 
       e[vj][vi] = 1; 
      } 

      if (num_edges % 10000 == 0) 
       cout << num_edges << endl; 
      else if (num_edges % 24380000 == 0) { 
       cout << endl; 
      } 
     } 
    } 
} 

回答

1

它可能不是你所看到的問題,但也有代碼中有幾個潛在的緩衝區溢出。例如:

while ((buffer[i] >= '0') && (buffer[i] <= '9')) 
{ 
    token[j++] = buffer[i]; 
    i++; 
} 

你真正應該檢查該指數不超過緩衝區的大小。

+0

我相信該文件是正確的,將是正確的 – user565447 2013-02-28 13:02:28

2

您將strstream用作緩衝區已被打破,幾乎可以肯定是不必要的。

此代碼會在您的strstream中放入部分行。所以當你逐行閱讀時,你可能會在每個緩衝區的結尾處得到一個不完整的行,然後在下一個行的開始處會出現另一條不完整的行。

f.read(block, N); 
    s.write(block, f.gcount()); 

也就是說,與在代碼中缺少任何數組邊界檢查(尤其是這個片段中,被別人提到的那些)相結合意味着這是一個汽車碰撞即將發生。

  e[vi][vj] = 1; 
      e[vj][vi] = 1; 

強烈建議您

  • 一個:完全去除strstream緩衝區。
  • b:考慮使用 std :: vector而不是手動分配緩衝區。
  • c:然後,您可以使用 使用at()函數進行邊界檢查訪問,這會拋出 異常。

不要擔心優化或性能,直到完成。

+0

謝謝,我會添加檢查數組中的邊界。但我使用它,因爲我需要良好的表現。由於實驗結果顯示向量比陣列更糟糕。 – user565447 2013-02-28 16:05:38

+0

@ user565447「_premature optimization is all of evil_」Donald Knuth,1974 – Roddy 2013-03-01 10:45:42

+0

是的,我同意。但我需要它。這不是一個商業項目。有必要爲科學而努力。 – user565447 2013-03-01 11:50:14