2013-02-03 2 views
0

C로 학습을하고 메모리 누수 상황을 식별하는 데 문제가 있습니다.C 메모리 누수 및 Valgrind 출력

첫째, 일부 코드 :


주요 기능 :

#define FILE_NAME "../data/input.txt" 

char * testGetLine(FILE *); 
int testGetCount(void); 

int main(void) 
{ 
    int count = 0; 
    FILE * fptr; 

    if ((fptr = fopen(FILE_NAME, "r")) != NULL) { 
     char * line; 
     while ((line = testGetLine(fptr)) != NULL) {    

      printf("%s", line); 
      free(line); count++; 
     } 

     free(line); count++; 

    } else { 
     printf("%s\n", "Could not read file..."); 
    } 

    // testing statements 
    printf("testGetLine was called %d times\n", testGetCount()); 
    printf("free(line) was called %d times\n", count); 

    fclose(fptr); 
    return 0; 
} 

의 getline 기능 :

#define LINE_BUFFER 500 

int count = 0; 

char * testGetLine(FILE * fptr) 
{ 
    extern int count; 

    char * line; 
    line = malloc(sizeof(char) * LINE_BUFFER); 
    count++; 

    return fgets(line, LINE_BUFFER, fptr); 
} 

int testGetCount(void) { 
    extern int count; 
    return count; 
} 

내 이해가 free 때마다 내가 내 testGetLine 함수를 호출해야 할 것입니다. 내 계산에 의하면 4 줄의 간단한 텍스트 파일에서 무료 번을 호출해야합니다. 나는 다음과 같은 출력 내 테스트 문으로 다음을 확인 : 내가에 문제가 있어요 것은

This is in line 01 
Now I am in line 02 
line 03 here 
and we finish with line 04 
testGetLine was called 5 times 
free(line) was called 5 times 

, Valgrind의 I alloc6 시간, 만 free5 번 호출하고 있다고 말한다.

HEAP SUMMARY: 
    in use at exit: 500 bytes in 1 blocks 
    total heap usage: 6 allocs, 5 frees, 3,068 bytes allocated 
500 bytes in 1 blocks are definitely lost in loss record 1 of 1 
    at 0x4C2B3F8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
    by 0x4007A5: testGetLine (testGetLine.c:13) 
    by 0x400728: main (tester.c:16) 
LEAK SUMMARY: 
    definitely lost: 500 bytes in 1 blocks 
    indirectly lost: 0 bytes in 0 blocks 
    possibly lost: 0 bytes in 0 blocks 
    still reachable: 0 bytes in 0 blocks 
     suppressed: 0 bytes in 0 blocks 

은 내가 메모리 관리 뭔가를 놓친 거지 느낌 : 여기에 Valgrind의에서 잘린 출력됩니다. valgrind가 사용하고 있다고 말하는 여섯 번째 메모리 할당은 어디에 있습니까? 어떻게 해방해야합니까?


후속 조사는 아드리안의 답변을 구현하는

testGetLine 조정 :

char * testGetLine(FILE * fptr) 
{ 
    extern int count; 

    char * line; 
    line = malloc(sizeof(char) * LINE_BUFFER); 
    count++; 

    if (fgets(line, LINE_BUFFER, fptr) == NULL) { 
     line[0] = '\0'; 
    } 

    return line; 
} 

main while 루프 조정 :

while ((line = testGetLine(fptr))[0] != '\0') {    

    printf("%s", line); 
    free(line); count++; 
} 

free(line); count++; 
+0

질문에 관련되지하지만, C,'는 sizeof (문자)에서'너무'의 malloc (sizeof 연산자'1'로 평가 보장 : 수익을 변경하고 대신 line를 반환 char) * LINE_BUFFER);'그냥 malloc (LINE_BUFFER); 일 수 있습니다. – shanet

+0

그게 알아두면 좋다, 덕분에 –

답변

2

fgets 반환 설명 :

성공시 str. 문자를 읽으려고 시도하는 중에 파일 끝이 인 경우 이 설정됩니다 (feof). 문자를 읽을 수 있기 전에 이런 일이 발생하면 포인터가 null 포인터가됩니다. str의 내용은 변경되지 않은 채로 남아 있습니다 ( ). 읽기 오류가 발생하면 오류 표시기 (ferror)는 이고 null 포인터도 반환됩니다 (단, str이 가리키는 내용이 변경되었을 수 있음).

fgets은 아무 것도 읽지 않을 때 malloc을 사용한 char *을 반환하지 않습니다.

따라서 마지막 통화의 malloc이 해제되지 않습니다.당신이 원하는대로 당신의 성명은 효과가 없습니다.

솔루션 : (

char * testGetLine(FILE * fptr) 
{ 
    extern int count; 

    char * line; 
    line = malloc(sizeof(char) * LINE_BUFFER); 
    count++; 
    fgets(line, LINE_BUFFER, fptr); 
    return line; 
} 
+0

나는 동의한다, 당신은 아마 단지 라인을 반환하고 싶다. –

+0

... 실제로 말이 되네요 ... 고마워요. 나는 지금 시험 할 것이다 –

+1

나는 또한 그 루프를 점검하면서 조정을 따라야 할 필요가있는 것처럼 보인다. 그렇지 않다면 작동한다. 다시 한 번 감사드립니다. –