在简单程序中使用ferror()时出现分段错误。为什么?

时间:2010-01-10 06:12:12

标签: c gdb

为什么以下代码会出现分段错误?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *file;
    file = fopen("text","r");
    if (file == NULL) printf("Error READING FILE");
    if (ferror(file)) printf("error reading file");    //line 9
    return 0;
}

在gdb中执行backtrace会产生: -

> #0  0x00007ffff7ad9d30 in ferror () from /lib/libc.so.6
> #1  0x00000000004005fa in main () at test.c:9

3 个答案:

答案 0 :(得分:7)

文件为NULL。您没有看到第一个printf,因为程序在刷新stdout之前崩溃了。

答案 1 :(得分:4)

如果fopen返回NULL,则文件未打开;您将NULL传递给ferror,这是无效的。您没有要传递的打开文件;这就是NULL的意思,它不能给你一个文件指针。 ferror用于获取与读取和写入文件相关的错误,一旦实际打开并且您可以使用该文件。

如果fopen失败,并且您想获得有关原因的更多信息,则需要查看errno.h中定义的errno global variable

#include <errno.h>

// ...snip...

if (file == NULL) 
  printf("Error READING FILE: %s\n", strerror(errno));

此示例显示如何获取描述错误的字符串;您还可以将errno中的值与其可能具有的值之一进行比较,并根据错误的不同做一些不同的操作。有关要比较的可能错误的列表,请参阅fopen man pagePOSIX spec。以下是您可以检查各种可能的错误的方法:

if (file == NULL) {
  int error = errno;  // copy it so other calls like printf don't modify it
  printf("Error READING FILE: %s\n", strerror(error));
  switch (error) {
  case EACCESS:
    // access was denied
    break;
  case ENOENT:
    // the file or one of its ancestors doesn't exist
    break;
    // etc...
  }
}

(这是我最初在另一个答案的评论中写的东西的扩展)

答案 2 :(得分:3)

如果第9行的file等于NULL,则在ferror()调用期间会发生Seg Fault。

如果文件为NULL(如第8行所确定),则不应执行第9行。

您的第8行代码应如下更改:

if (file == NULL)
{
    printf("Error READING FILE");
    return 1;
}
NB:我可能对此非常不对,自从我做完C / C ++以来已经有一段时间了