我有这段代码,它应该逐个字符读取文本文件,然后用它做一些事情,但代码在第 6 行一直出现段错误。
#include <stdio.h>
int main(void)
{
printf("an");
FILE* fp = fopen("~/pset5/dictionaries/small", "r");
for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
{
printf("bn");
}
return 0;
}
肯定发生了一些奇怪的事情,因为它甚至没有将"an"
打印到终端,甚至在错误发生之前很难调用printf
。我已经用gdb运行了该程序,这就是它失败的地方。
6 for (int a = fgetc(fp); a != EOF; a = fgetc(fp))
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
_IO_getc (fp=0x0) at getc.c:38
38 getc.c: No such file or directory.
我也像valgrind --leak-check=full ./test
一样使用 valgrind 运行它,test 是可执行文件的名称,这是相关的错误消息:
==7568== Invalid read of size 4
==7568== at 0x4EA8A21: getc (getc.c:38)
==7568== by 0x4005ED: main (test.c:6)
==7568== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7568==
==7568==
==7568== Process terminating with default action of signal 11 (SIGSEGV)
==7568== Access not within mapped region at address 0x0
我在这里真的很茫然,有人可以解释一下这个分段错误是怎么回事,为什么不是第一次调用printf
打印任何东西?
正如调试器所说 (fp=0x0
(,您正在使用空指针调用fgetc
。这就是导致崩溃的原因。
fp
为 null,因为fopen
调用失败。您需要检查错误。
打开文件失败,因为很可能您没有名为~
的目录。回想一下,将~
扩展到主目录是由 shell 在键入命令时完成的。fopen
只采用真实的文件名。
您忘记根据 NULL 检查fopen()
的返回值,这表示尝试打开文件时出错。
您的for
循环忙于使用 NULL 指针,因此会出现段错误。
检查全局变量errno
以了解有关您的案例中究竟出了什么问题的更多信息。