Reputation: 15058
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
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
Reputation: 107889
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