如何解决 Valgrind 显示的内存泄漏错误?

How to solve the memory leak error shown by Valgrind?

下面是链表的基本代码。我只是接受输入然后显示它。 我正在动态地提供内存并释放我认为需要释放的内存。 如果我错了,请纠正我,但是 new_node 应该在 for 循环 中自动释放。 我是新手,不了解内存泄漏的确切概念,也不知道如何解决 Valgrind 显示的错误。

代码:

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

typedef struct node
{
    int data;
    struct node *next;
}
node;

int main(void)
{
    node *list = NULL;
    int num;
    for (int i = 0; i < 5; i++)
    {
        node *new_node;
        printf("Enter a number: ");
        scanf("%i", &num);
        new_node = malloc(sizeof(node));
        new_node->data = num;
        new_node->next = list;
        list = new_node;
    }
    //display
    node *temp;
    temp = list;
    while(temp != NULL)
    {
        printf("%d\n",temp->data);
        temp = temp->next;
    }

    free(list);
}

Valgrind 错误:


practice/ $ make linked
practice/ $ valgrind ./linked 
==27973== Memcheck, a memory error detector
==27973== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27973== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==27973== Command: ./linked
==27973== 
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 4
Enter a number: 5
5
4
3
2
1
==27973== 
==27973== HEAP SUMMARY:
==27973==     in use at exit: 64 bytes in 4 blocks
==27973==   total heap usage: 6 allocs, 2 frees, 1,104 bytes allocated
==27973== 
==27973== 48 bytes in 3 blocks are indirectly lost in loss record 1 of 2
==27973==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==27973==    by 0x4011BD: main (linked.c:20)
==27973== 
==27973== 64 (16 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==27973==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==27973==    by 0x4011BD: main (linked.c:20)
==27973== 
==27973== LEAK SUMMARY:
==27973==    definitely lost: 16 bytes in 1 blocks
==27973==    indirectly lost: 48 bytes in 3 blocks
==27973==      possibly lost: 0 bytes in 0 blocks
==27973==    still reachable: 0 bytes in 0 blocks
==27973==         suppressed: 0 bytes in 0 blocks
==27973== 
==27973== For lists of detected and suppressed errors, rerun with: -s
==27973== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

请注意,现代 C 不需要单独声明和初始化变量。

    node *temp;
    temp = list;
    while(temp != NULL)
    {
        printf("%d\n",temp->data);
        temp = temp->next;
    }

可以很容易地表示为:

    for (node *temp = list; temp != NULL; temp = temp->next) {
        printf("%d\n", temp->data);
    }

当您 free(list) 时,您只是释放 list 指向的节点。您需要遍历列表,确保保存指向下一个节点的指针(如果有的话),这样您就不会 free 该指针并丢失它,从而使列表的其余部分无法访问。这会导致内存泄漏。

    for (node *temp = list; temp != NULL; ) {
        if (temp->next != NULL) {
            node *next = temp->next;
            free(temp);
            temp = next;   
        }
        else {
            free(temp);
        }
    }