2016-06-11 25 views
0

Bitte schauen Sie auf den folgenden Code:Warum schlägt fclose() fehl?

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

} 

Diese Codekompilierung geht, aber Abstürze beim Laufen. Weißt du, warum?

Wenn ich jedoch zwischen fclose() und printf() (die letzten zwei Zeilen des Codes) wechseln, wird der Code erfolgreich ausgeführt und den Inhalt von "newfile" gedruckt. Was ist der Unterschied zwischen diesen beiden Fällen?

+0

Warum nicht überprüfen Sie den Rückgabewert von 'fopen' –

+1

' void main' ist falsch. – melpomene

+0

Verwenden Sie auch 'fstat (fileno (file), & file_st);' –

Antwort

0

Ein guter Compiler wird Sie über mindestens einen Fehler im Code informieren. Von gcc -Wall -O:

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

Je nach Umgebung, könnte ein Argument printf Weglassen verursacht es Müll zu drucken, zum Absturz zu bringen, Müll und Absturz zu drucken, nichts zu drucken, nichts und Absturz zu drucken, oder entweder drucken Müll oder nichts und den Speicher des Programms in einem beschädigten Zustand verlassen, so dass bestimmte Operationen fehlschlagen. Insbesondere ist es sicherlich möglich, dass das fehlende Argument dazu führt, dass fclose abstürzt, aber wenn Sie printf dazwischen aufrufen, stellt das den Speicher des Programms in einen gültigen Zustand zurück. Es ist unmöglich, mit Sicherheit zu sagen, was passiert, weil alles davon abhängt, wie genau das Programm im Speicher angeordnet ist und wie es den Erwartungen des Betriebssystems und der Funktionsweise des Compilers entspricht. In C, wenn etwas schief läuft, sind alle Wetten ausgeschaltet.

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

Entfernen Sie den Operator sizeof aus diesem Ausdruck. Ich bin überrascht, dass es kompiliert. Es gibt die Größe eines int zurück, der 4 oder 8 ist. Nicht die Größe der Datei. Sie überholen den Puffer.

Auch das Drucken des Rückgabewerts fclose() ist sinnlos. Sie müssen errno oder strerror() drucken, wenn Fehler zurückgegeben wird.