简体   繁体   中英

How to solve the memory leak error shown by Valgrind?

This below is a basic code for linked list. I am just taking input and then displaying it. I am dynamically giving memory and freeing the memory which I think needs to be freed. Please correct me if I am wrong but new_node should get freed automatically as it comes out of for loop . I am new and I don't understand the exact concept of memory leak and I don't know how to solve the errors shown by Valgrind.

Code:

#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 Error:


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)

Please note that modern C does not require separate declaration and initialization of variables.

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

Can be readily expressed as:

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

When you free(list) you are only freeing the node pointed to by list . You need to iterate over the list, making sure to save a pointer to the next node if there is one, so you don't free that pointer and lose it, making the rest of the list inaccessible. This would result in a memory leak.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM