以下是在读取空文件时给出分段错误的示例代码。
#include <stdio.h>
main()
{
FILE *fp;
int i = 0;
char buffer[20];
printf("1\n");
fp = fopen("/home/amadhab/aa", "r+");
printf("2\n");
i = fread(buffer, 1, 1, fp);
printf("3\n");
printf("i = %d\n", i);
}
将o / p视为
1
2
Segmentation fault
fread()
无法读取空(0KB)文件吗?
答案 0 :(得分:6)
如果程序有效,会发生什么:
1 2 3 i = 0
当fread()
失败时,应返回0(或小于请求的项目数的数字)。但是,这不会发生。这可能是因为fp
为空。您不能将null参数传递给fread()
。可能fp
为空,因为/home/amadhab/aa
不存在。尝试使用它来代替打开文件:
#include <assert.h>
fp = fopen("/home/amadhab/aa", "r+");
assert(fp != NULL);
或者,有关更多信息,
#include <err.h>
const char *fname = "/home/amadhab/aa";
fp = fopen(fname, "r+");
if (!fp)
err(1, "%s", fname)
请注意,err()
函数是BSD扩展,但如果担心可移植性,则可以在其他系统上使用strerror()
或perror()
。
从n1516第7.21.8.1节:
fread
函数从ptr
指向的数组中读取nmemb
的大小由size
指定的stream
个元素。 {1}}。
请注意,NULL
未指向流,因此通过传递NULL
,您违反了fread()
功能的前提条件。这在7.1.4节中明确说明:
如果[library]函数的参数具有无效值(例如[...]空指针[...])[...],则行为未定义。
答案 1 :(得分:1)
对于空文件,不无法执行任何操作。 Source
正如其他人已经指出的那样,错误与函数本身无关。
答案 2 :(得分:1)
在您的代码中
fp = fopen("/home/amadhab/aa", "r+");
没有成功检查fopen()
返回值。如果fopen()
失败,它将返回NULL(在fp
中收集)并且随后使用用于收集返回值的变量fp
将导致{{3} } 注意。这就是
fread(buffer, 1, 1, fp); // note the usage of fp here
导致分段错误。
为避免这种情况,您应立即检查fopen()
的返回值,如果失败,则应避免访问fp
。
注意:只是一个建议,学习使用调试器[如Linux上的gdb
]并逐步完成您的应用程序。大多数情况下,它将查明确切的问题。
注意:请参阅附件J,C99
,作为未定义行为背后的原因,
库函数的参数具有无效值或具有可变参数数量的函数不期望的类型(7.1.4)。
并且,认为 无效值,FILE *
将传递给fread()
。
答案 3 :(得分:1)
读取空文件时,Fread不会失败。你没有检查流开放 这是正确打开的。
fp = fopen("/home/amadhab/aa", "r+");
在这种情况下,如果该文件的打开失败。现在fp的值为NULL。
i = fread(buffer, 1, 1, fp);
现在您正在访问NULL
文件流。这就是分段错误的原因。为了避免这种情况,你必须检查条件。
if ( ( fp = fopen("/home/amadhab/aa", "r+") ) == NULL ){
perror("fopen");
exit(5);
}