简体   繁体   English

在C ++中读取文件引发段错误

[英]Reading File in C++ throwing Seg Fault

When trying to read tokens from a file in C++, I receive a seg fault. 尝试从C ++文件中读取令牌时,出现段错误。 Just to play with some things, I tried reading over the file and just printing and surprisingly if you uncomment the code for the first file read and then read the second file everything works fine. 只是为了玩弄一些东西,我试图读取文件并打印,但令人惊讶的是,如果您取消注释读取的第一个文件的代码,然后读取第二个文件,一切正常。 If you leave the commented code commented, you receive the seg fault upon closing the first file. 如果将注释的代码保留为注释状态,则在关闭第一个文件时会收到seg错误。 This could be an issue with the library on my school machine... The stack trace is below for the segfault (below the code itself). 这可能是我的学校机器上的库出现问题... segfault的堆栈跟踪在下面(在代码本身下面)。 It's also interesting to note that I do not have to do this 'hack' for each file I open, once the dummy-commented-code has been executed all subsequent streams open just fine. 有趣的是,我不必对打开的每个文件都进行这种“破解”,一旦执行了虚拟注释代码,所有后续流都将打开。

int main()
{
ifstream myfile1;
ifstream myfile2;

int m; //number of elements in 1st file
int n; //number of elements in 2nd file
int counter = 0;

int x = 0;
int y = 0;
int theta = 0;

Minutiae* minutiae;
minutiae = new Minutiae(x,y,theta,0);

Minutiae* file1_minutiaes;
Minutiae* file2_minutiaes;

int num;

//Some Error is caused with segfault if i Try to fill the minutiae array and then close the file unless i do this first
/*////////////////////
  myfile1.open("2a");


  if (myfile1.is_open())
  {

    counter = 0;

    while (!myfile1.eof() )
    {

     myfile1 >> x >> y >> theta;
     minutiae = new Minutiae(x,y,theta,counter);
     counter++;
    }

    myfile1.close();

  }
  else
  {
  cout << "unable to open file1" << endl;
  return(0);
  }
*/////////////////////////////////////




  myfile1.open("2a");

  if (myfile1.is_open())
  {
    counter = 0;
    myfile1 >> m;

    file1_minutiaes = new Minutiae[m];

    while (!myfile1.eof() )
    {

     myfile1 >> x >> y >> theta;

     //minutiae = new Minutiae(x,y,theta,counter);
     //file1_minutiaes[counter] = *minutiae;
     file1_minutiaes[counter] = *(new Minutiae(x,y,theta,counter));
     counter++;

    }
    myfile1.close();
    cout << "closing file1" << endl;

  }
  else
  {
  cout << "unable to open file1" << endl;
  return(0);
  }

////////////////////////////////
}

And the stack trace: 和堆栈跟踪:

Starting program: /cs/student/dick_man_chini/Desktop/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00c47a72 in _int_free () from /lib/libc.so.6
(gdb) up
#1  0x006d9342 in operator delete(void*) () from /usr/lib/libstdc++.so.6
(gdb) up
#2  0x006d939e in operator delete[](void*) () from /usr/lib/libstdc++.so.6
(gdb) up
#3  0x00686130 in std::basic_filebuf<char, std::char_traits<char> >::_M_destroy_internal_buffer() () from /usr/lib/libstdc++.so.6
(gdb) up
#4  0x006874d1 in std::basic_filebuf<char, std::char_traits<char> >::close() () from /usr/lib/libstdc++.so.6
(gdb) up
#5  0x006894a6 in std::basic_ifstream<char, std::char_traits<char> >::close() () from /usr/lib/libstdc++.so.6
(gdb) up
#6  0x08048e96 in main ()
(gdb) up
Initial frame selected; you cannot go up.
(gdb) 

Thanks in advance. 提前致谢。

The common process for reading files: 读取文件的常见过程:

myfile1.open("2a");
// Note the change in the next line
if (!myfile1)
{
    cout << "unable to open file1" << endl;
    return(0);
}

counter = 0;

// Note, this line differs between the two examples.
myfile1 >> m;

file1_minutiaes = new Minutiae[m];

// Note the change in the following line
while (myfile1 >> x >> y >> theta)
{
    //minutiae = new Minutiae(x,y,theta,counter);
    //file1_minutiaes[counter] = *minutiae;
    file1_minutiaes[counter] = *(new Minutiae(x,y,theta,counter));
    counter++;
}
myfile1.close();
cout << "closing file1" << endl;

I suggest you use a std::vector instead of an array: 我建议您使用std::vector而不是数组:

  std::vector<Minutiae> file1_minutiaes;

When processing data files, a good idea is to use dynamic containers. 处理数据文件时,一个好主意是使用动态容器。

If m is smaller than the actual number of rows of data in your file, you'll stomp over random memory, quite possibly causing corruption and the crash you're seeing. 如果m小于文件中数据的实际行数,那么您将在随机内存上sto脚,这很可能导致损坏和崩溃。 Your while loop should also make sure than you don't exceed m iterations. while循环还应确保不超过m次迭代。

In C++ land however you can use std::vector to manage all your memory for you: Read each line, create a Minutiae on the stack, and then push it onto the vector (alternately use new and store smart pointers of some sort). 但是,在C ++领域中,您可以使用std :: vector来管理所有内存:读取每一行,在堆栈上创建一个Minutiae ,然后将其压入vector(或者使用new并存储某种类型的智能指针)。

A) as mentioned above, your first attempt is actually leaking, as you just have a pointer, instead of an actual array or an array of pointers, since what new is returning is a Minutiae pointer, NOT a Minutiae. A)如上所述,您的第一次尝试实际上是在泄漏,因为您只有一个指针,而不是实际的数组或指针数组,因为新返回的是Minutiae指针,而不是Minutiae。 Your second attempt is returning a Minutiae pointer, then dereferencing it to get a Minutiae, which is then copied using the assignment operator to the Minutiae created in your array. 第二次尝试是返回Minutiae指针,然后对其取消引用以获取Minutiae,然后使用赋值运算符将其复制到在数组中创建的Minutiae。 You might want to read up on pointers just to be sure you understand the differences. 您可能想要阅读指针,只是为了确保您了解差异。

B) first thing I'd do is ensure that your data is formatted absolutely correctly according to your assumptions (integer followed by integer followed by integer * however many rows). B)我要做的第一件事是确保您的数据根据​​您的假设进行了绝对正确的格式化(整数,然后是整数,然后是整数*,但是行很多)。 After that, you should probably use eof() || 之后,您可能应该使用eof()|| bad() instead of just eof(). bad()而不只是eof()。 Or fail I think uses both of them. 还是失败,我认为两者都使用。 Look at the reference for an ifstream, but if memory serves me right using just eof will not safeguard you in case reading the file runs into some other error, which could be the cause of your SIGSEV. 查看ifstream的参考,但是如果仅使用eof可以为我提供正确的内存,以防在读取文件时遇到其他错误(可能是SIGSEV的原因)而无法保护您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM