CrazySynthax
CrazySynthax

Reputation: 15058

Why does fclose() fail?

Please look at the following code:

#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);

}

This code passes compilation, but crashes while running. Do you know why?

However, if I switch between the fclose() and printf() (the last two lines of the code), then the code runs successfully and prints the content of "newfile". What is the difference between these two cases?

Upvotes: 1

Views: 1933

Answers (2)

user207421
user207421

Reputation: 311048

buf = (char*)malloc(sizeof(file_st.st_size+1));

Remove the sizeof operator from this expression. I'm surprised it compiles. It is returning the size of an int, which is 4 or 8. Not the size of the file. You are overrunning the buffer.

Also, printing the return value of fclose() is futile. You need to print errno or strerror() if it returns failure.

Upvotes: 1

A good compiler will tell you about at least one mistake in the code. From gcc -Wall -O:

a.c:24:5: warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat=]
     printf("fread return value is: %d\n");
     ^

Depending on your environment, omitting an argument to printf could cause it to print garbage, to crash, to print garbage and crash, to print nothing, to print nothing and crash, or to either print garbage or nothing and leave the program's memory in a corrupt state so that certain operations fail. In particular, it's certainly possible that the missing argument causes fclose to crash, but that if you call printf in between, that restores the program's memory to a valid state. It's impossible to say for sure what happens because it all depends on exactly how the program is arrange in memory and how this matches the expectations of the operating system and how the compiler works. In C, when something goes wrong, all bets are off.

Upvotes: 0

Related Questions