为什么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”的内容。这两种情况有什么区别?

+0

为什么不检查'fopen'的返回值 –

+1

'void main'是错误的。 – melpomene

+0

也可以使用'fstat(fileno(file),&file_st);' –

一个好的编译器会告诉你至少在代码中有一个错误。从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()是徒劳的。如果返回失败,则需要打印errnostrerror()