2016-06-11 6 views
0

다음 코드를보고하십시오 : 실행하는 동안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);를 사용한다. ' –

답변

0

좋은 컴파일러는 코드에서 적어도 하나의 실수에 대해 알려줍니다. 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에서 무언가가 잘못 될 경우 모든 배팅이 해제됩니다.

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

이 표현식에서 sizeof 연산자를 제거하십시오. 나는 그것이 놀랍다. int의 크기를 4 또는 8로 반환합니다. 파일 크기가 아닙니다. 버퍼 오버런입니다.

또한 fclose()의 반환 값을 인쇄하는 것은 효과가 없습니다. 실패가 반환되면 errno 또는 strerror()을 인쇄해야합니다.

관련 문제