2017-01-29 1 views
-1

나는이 함수 내 프로그램과 fopen()NULL 포인터를 반환하는 1019 시간에 1050 번 호출오류 동안 자주

char* Readfiletobuffer(char* file, FILE* fp){ 
    char * buffer; 
    int file_size; 

    fp = fopen(file, "r"); 

    if (fp != NULL) { 
     fseek(fp, 0, SEEK_END); 
     file_size = ftell(fp); 
     buffer = (char*) malloc((file_size + 1) * sizeof(char)); 
     fseek(fp, 0, SEEK_SET); 
     fread(buffer, file_size, 1, fp); 
     buffer[file_size] = '\0'; 
     return buffer; 
    } else { 
     printf("error loading file"); 
    } 

    fclose(fp); 
} 

에게 있습니다 FOPEN.

그것은, 그것은 항상 파일에 의존하지 않는

1019 그래서 시간 나는 그것이 메모리를 해제 뭔가 생각하지만, 왜 fclose() 호출이 충분하지 일?

누군가 아이디어가 있습니까?

+7

'fclose (fp);'돌아 가기 버퍼; – BLUEPIXY

+1

함수를 호출 할 때마다'fop'()는'fp'가 null이 아닌 한'fclose()'없이 호출됩니다. 함수가 반환되기 전에 fclose가 일어나야합니다. 그렇지 않으면 파일이 열려 있습니다. – Munir

+3

왜'fp'가 지역 변수가 아닌이 함수의 매개 변수입니까? 호출자가 전달한 값은 무시됩니다. –

답변

2

프로그램은 많은 기능이 오류 코드를 할당하는 전역 변수 인 errno으로 알려줍니다. 사람이 읽을 수있는 오류 메시지를 제공하기 위해 strerror과 결합하면 오류 처리가 이와 같이 변경됩니다.

#include <errno.h> 
#include <string.h> 

... 

fp = fopen(file, "r"); 
if (fp == NULL) { 
    fprintf(stderr, "Could not open '%s': %s", file, strerror(errno)); 
    exit(1); 
} 

fseek(fp, 0, SEEK_END); 
file_size = ftell(fp); 
... 

early exit의 사용은 경우/다른 블록에 둥지를 전체 기능을 갖는 제거합니다.

또한 파일 작업의 나머지 부분을 확인하지 않습니다. fseek, ftellfread 모두 실패 할 수 있습니다. 모두에 대해 비슷한 검사가 필요합니다. 오류 처리를 통해 코드를 처리하는 대신 몇 곳에서 처리하는 것을 잊어 버리는 대신 작은 래퍼를 작성하는 것이 좋습니다.

FILE *open_file(const char *filename, const char *mode) { 
    FILE *fp = fopen(filename, mode); 
    if(fp == NULL) { 
     fprintf(
      stderr, "Could not open '%s' for '%s': %s\n", 
      filename, mode, strerror(errno) 
     ); 
     exit(1); 
    } 

    return fp; 
} 

오류 처리가 최선이 아니므로 오류가 발생하면 종료됩니다. 학습 C의이 단계에서 오류가 발생하면 즉시 구제하는 것이 가장 좋습니다. return NULL 확률과 같은 일을했다면 널 포인터를 처리하는 오류 처리 기능이 없으므로 나중에 코드에서 신비로운 문제와 충돌을 일으킬 수 있습니다. 지금은 가능한 한 오류에 가깝게 불을 끄고 잡는 것이 가장 좋습니다.


스포일러 경고 : 파일을 닫지 않아 프로세스에 파일 핸들이 부족합니다. @BLUEPIXY correctly points out in the comments으로 정상적으로 돌아온 후 fclose은 파일을 열 수없는 경우에만 발생합니다.

파일 포인터를 전달 중이므로 나중에 사용 하시겠습니까? 이 경우 열려있는 많은 파일을 보관할 수 없으며 코드를 재 설계해야합니다. 그렇지 않다면 함수가 그것을 여는 것이므로 전달할 이유가 없습니다.

-Wall으로 경고가 켜져 있다면 경고가 표시되어야합니다.

test.c:23:1: warning: control may reach end of non-void function [-Wreturn-type] 
} 

파일을 열지 못하면 아무것도 반환되지 않으며 확인되지 않습니다.

경고를 무시하지 마십시오. 모두 수정하십시오. 이 경고를 조사하면 문제를 지적했을 것입니다.

  • 파일 작업을 모두 확인하여 성공했는지 확인하십시오.
  • 오류 메시지에 strerror(errno)을 포함하면 실패한 이유를 알 수 있습니다.
  • 모든 경고를 조사하고 수정하십시오.