基本堆栈中的内存泄漏
Memory leak in basic 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)
您的内存泄漏来自 fopen
调用,正如您从泄漏分配的堆栈跟踪中看到的那样——它来自您调用 fopen
打开文件 (它在堆上分配一个缓冲区结构来管理文件)然后从不调用 fclose
.
读完文件后添加对 fclose
的调用,它将消失。
我正在研究一个真正简单的堆栈实现,但我似乎无法弄清楚为什么会发生内存泄漏。我对代码的期望是在 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)
您的内存泄漏来自 fopen
调用,正如您从泄漏分配的堆栈跟踪中看到的那样——它来自您调用 fopen
打开文件 (它在堆上分配一个缓冲区结构来管理文件)然后从不调用 fclose
.
读完文件后添加对 fclose
的调用,它将消失。