基本堆栈中的内存泄漏

时间:2015-07-25 20:02:05

标签: c stack

我正在开发一个真正简单的堆栈实现,而我似乎无法弄清楚为什么会出现内存泄漏。我对代码的期望是在push()中分配了5个节点,在displayAndDestroy()中释放了5个节点。但是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)

1 个答案:

答案 0 :(得分:6)

您的内存泄漏来自fopen调用,正如您可以从泄漏分配的堆栈跟踪中看到的那样 - 它来自于您调用fopen来打开文件(分配的文件)堆上的缓冲区结构来管理文件)然后永远不要调用fclose

在您阅读完文件后,向fclose添加电话,该电话将会消失。