fread 对空 (0kb) 文件的行为
behaviour of fread for empty (0kb) files
这是在读取空文件时给出分段错误的示例代码。
#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) 文件?
No fread 不会 对空文件失败。 Source.
正如其他人已经指出的,该错误与函数本身无关。
如果程序运行,应该会发生什么:
1
2
3
i = 0
当fread()
失败时,它应该 return 0(或小于请求的项目数的数字)。但是,这不会发生。这可能是因为 fp
为空。不允许将空参数传递给 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 节:
The fread
function reads, into the array pointed to by ptr
, up to nmemb
elements whose size is specified by size
, from the stream pointed to by stream
.
请注意 NULL
不指向流,因此通过传递 NULL
您违反了 fread()
函数的先决条件。这在第 7.1.4 节中明确说明:
If an argument to a [library] function has an invalid value (such as [...] a null pointer [...]) [...], the behavior is undefined.
在你的代码中
fp = fopen("/home/amadhab/aa", "r+");
fopen()
return 值没有成功检查。如果 fopen()
失败,它将 return NULL(在 fp
中收集)和随后使用的变量 fp
用于收集 return value 将导致 undefined behaviour Note。这就是
中正在发生的事情
fread(buffer, 1, 1, fp); // note the usage of fp here
导致分段错误。
为避免这种情况,您应该立即检查 fopen()
的 return 值,如果失败,您应该避免访问 fp
.
注意:只是一个建议,学习使用调试器 [如 linux 上的 gdb
] 并单步执行您的应用程序。大多数时候,它 会 查明确切的问题。
注意:请参阅附件 J,C99
,作为未定义行为背后的原因,
An argument to a library function has an invalid value or a type not expected by a function with variable number of arguments (7.1.4).
而且,NULL 被认为是 将要传递给 fread()
的 FILE *
的无效值。
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);
}
这是在读取空文件时给出分段错误的示例代码。
#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) 文件?
No fread 不会 对空文件失败。 Source.
正如其他人已经指出的,该错误与函数本身无关。
如果程序运行,应该会发生什么:
1 2 3 i = 0
当fread()
失败时,它应该 return 0(或小于请求的项目数的数字)。但是,这不会发生。这可能是因为 fp
为空。不允许将空参数传递给 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 节:
The
fread
function reads, into the array pointed to byptr
, up tonmemb
elements whose size is specified bysize
, from the stream pointed to bystream
.
请注意 NULL
不指向流,因此通过传递 NULL
您违反了 fread()
函数的先决条件。这在第 7.1.4 节中明确说明:
If an argument to a [library] function has an invalid value (such as [...] a null pointer [...]) [...], the behavior is undefined.
在你的代码中
fp = fopen("/home/amadhab/aa", "r+");
fopen()
return 值没有成功检查。如果 fopen()
失败,它将 return NULL(在 fp
中收集)和随后使用的变量 fp
用于收集 return value 将导致 undefined behaviour Note。这就是
fread(buffer, 1, 1, fp); // note the usage of fp here
导致分段错误。
为避免这种情况,您应该立即检查 fopen()
的 return 值,如果失败,您应该避免访问 fp
.
注意:只是一个建议,学习使用调试器 [如 linux 上的 gdb
] 并单步执行您的应用程序。大多数时候,它 会 查明确切的问题。
注意:请参阅附件 J,C99
,作为未定义行为背后的原因,
An argument to a library function has an invalid value or a type not expected by a function with variable number of arguments (7.1.4).
而且,NULL 被认为是 将要传递给 fread()
的 FILE *
的无效值。
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);
}