为什么以下代码会出现分段错误?
#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
答案 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 page或POSIX 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 ++以来已经有一段时间了