2015-07-25 3 views
0

Я работаю над реализацией простой стека, и я не могу понять, почему у меня утечка памяти. То, что я ожидаю от кода, состоит в том, что 5 узлов распределены в push(), и 5 узлов освобождаются в displayAndDestroy(). Но Valgrind говорит, что я выделил 6 узлов данных и только освободил 5. Я смотрел на это некоторое время, и я не совсем уверен, где я ошибся.Утечка памяти в базовом стеке


#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct STACK{ 
    char data[100]; 
    struct STACK *next; 
} stack; 

stack *push(stack *oldTop, char *data) 
{ 
    stack *newTop = malloc(sizeof(stack)); 
    newTop->next = oldTop; 

    if(!data){ 
     strcpy(newTop->data, newTop->next->data); 
    } else{ 
     strcpy(newTop->data, data); 
    } 

    return(newTop); 
} 

void displayAndDestroy(stack *top) 
{ 
    stack *currentTop = top; 
    stack *temp; 

    int i=0; 
    while(currentTop){ 

     printf("stack%d: %s\n", i, currentTop->data); 

     temp = currentTop->next; 
     free(currentTop); 
     currentTop = temp; 

     i++; 
    } 
} 

stack *initializer(stack *top, char *fileName) 
{ 
    char word[100]; 
    char ch; 

    FILE *fr = fopen(fileName, "r"); 

    int i=0; 
    while((ch=fgetc(fr)) != EOF){ 
     if(ch == '>'){ 
      fscanf(fr, "%s\n", word); 
      top = push(top, word); 
      i++; 
     } 
    } 

    return top; 
} 

int main() 
{ 
    stack *top = NULL; 

    top = initializer(top, "testData.txt"); 

    displayAndDestroy(top); 

    return 0; 
} 

testData.txt

garbage 

>stringone 
>2nd string 
>s3 

moregarbage 
>THE 4FOURTH4 STRING 

>5 
finalgarbage 

Valgrind говорит:

==19446== Memcheck, a memory error detector 
==19446== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==19446== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info 
==19446== Command: ./test 
==19446== 
stack0: 5 
stack1: THE 
stack2: s3 
stack3: 2nd 
stack4: stringone 
==19446== 
==19446== HEAP SUMMARY: 
==19446==  in use at exit: 568 bytes in 1 blocks 
==19446== total heap usage: 6 allocs, 5 frees, 1,128 bytes allocated 
==19446== 
==19446== 568 bytes in 1 blocks are still reachable in loss record 1 of 1 
==19446== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==19446== by 0x4EA544C: __fopen_internal (iofopen.c:73) 
==19446== by 0x400880: initializer (test.c:47) 
==19446== by 0x400921: main (test.c:65) 
==19446== 
==19446== LEAK SUMMARY: 
==19446== definitely lost: 0 bytes in 0 blocks 
==19446== indirectly lost: 0 bytes in 0 blocks 
==19446==  possibly lost: 0 bytes in 0 blocks 
==19446== still reachable: 568 bytes in 1 blocks 
==19446==   suppressed: 0 bytes in 0 blocks 
==19446== 
==19446== For counts of detected and suppressed errors, rerun with: -v 
==19446== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
+0

Положите 'printf' в свой' push' для подтверждения. См. Http://ericlippert.com/2014/03/05/how-to-debug-small-programs/ – usr2564301

+0

Термин 'STACK' для структуры плохой, потому что это только один элемент, а не весь стек. Кроме того, я ожидаю, что стек будет «poppable». Вместо этого вы начинаете с первого элемента, по существу используя его в качестве очереди. – GolezTrol

+0

Это незавершенное производство. Когда я сделал все сразу, я нашел слишком грязным для отладки. – user2012968

ответ

6

Ваша утечка памяти из fopen, как вы можете видеть из трассировки стека утечки - это происходит из-за того, что вы вызываете fopen, чтобы открыть файл (который выделяет структуру буфера в куче для управления файлом), а затем никогда не вызывает fclose.

После того, как вы закончите читать файл, пойдите в fclose, и он исчезнет.

+0

Черт побери. Я подумал, что это было что-то глупое. Благодаря! – user2012968