2013-02-28 84 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

相关问题