2013-02-03 71 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; 
} 

我的理解是,每次我打电话给我的testGetLine函数时,我都需要拨打free。据我所知,在一个简单的四行文本文件中,我需要拨打免费次。我确认,在下面的输出我的测试语句:

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的说,我alloc 次,而且只调用free 倍。下面是从Valgrind的输出被截断:

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说我正在使用的第六个内存分配在哪里?我应该如何释放它?


跟进落实阿德里安的回答

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(char)的'是保证评价为'1'所以'的malloc(的sizeof( char)* LINE_BUFFER);''可以只是'malloc(LINE_BUFFER);'。 – shanet

+0

这是很好的知道,谢谢 –

回答

2

fgets回报说明:

成功时,函数返回str。如果在尝试读取字符时遇到 文件结束,则eof指示符为 set(feof)。如果在读取任何字符之前发生这种情况,则返回的指针为空指针(并且str的内容保持 不变)。如果发生读取错误,则错误指示符(ferror)为 set,同时返回空指针(但由 str指向的内容可能已更改)。

fgets没有读取任何内容时,它不会返回您使用malloc所在的char *

因此,上次调用中的malloc未被释放。你以后的陈述不能按你的想法工作。

解决方法:改变你的收益和回报,而不是line

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

它看起来像我也需要跟随这种变化,同时对while循环检查进行调整,否则,它会起作用。再次感谢 –