为什么fclose()失败?
问题描述:
请看下面的代码:为什么fclose()失败?
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
void main() {
struct stat file_st;
int size=0, ret=0;
char* buf=NULL;
FILE* file = fopen("newfile", "r");
if (file==NULL) {
printf("error");
exit(1);
}
if (stat("newfile", &file_st)!=0) {
printf("stat failed\n");
exit(1);
}
buf = (char*)malloc(sizeof(file_st.st_size+1));
buf[file_st.st_size]='\0';
ret = fread(buf, 1, file_st.st_size, file);
printf("fread return value is: %d\n");
ret = fclose(file);
printf("fclose return value: %d\n", ret);
printf("%s\n", buf);
}
此代码经过编译,但是崩溃运行时。你知道为什么吗?但是,如果我在fclose()和printf()(代码的最后两行)之间切换,那么代码将成功运行并打印“newfile”的内容。这两种情况有什么区别?
答
一个好的编译器会告诉你至少在代码中有一个错误。从gcc -Wall -O
:根据您的环境
a.c:24:5: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]
printf("fread return value is: %d\n");
^
,省略了一个参数printf
导致其无法打印乱码,死机,打印垃圾和崩溃,更不要打印,打印什么和崩溃,或者要么打印垃圾或什么也没有,并使程序的内存处于损坏状态,以便某些操作失败。尤其是,缺少的参数肯定有可能导致fclose
崩溃,但如果您在中间调用printf
,则会将程序内存恢复到有效状态。无法确切地说出发生了什么,因为这完全取决于程序在内存中的安排方式,以及它如何与操作系统的期望以及编译器的工作方式相匹配。在C中,当出现问题时,所有投注都关闭。
答
buf = (char*)malloc(sizeof(file_st.st_size+1));
从该表达式中删除sizeof
运算符。我很惊讶它编译。它返回一个int的大小,它是4或8.不是文件的大小。你超出缓冲区。
而且,打印返回值fclose()
是徒劳的。如果返回失败,则需要打印errno
或strerror()
。
为什么不检查'fopen'的返回值 –
'void main'是错误的。 – melpomene
也可以使用'fstat(fileno(file),&file_st);' –