c - 不明白 Valgrind 中内存泄漏显示的来源

标签 c data-structures valgrind singly-linked-list

我花了一天的大部分时间尝试使用 CRUD 操作构建我自己的单链表程序,我偶然发现了一些项目,并找到了下面的程序,我将其用作引用。在这个程序上运行 valgrind 尽管它显示内存泄漏,但我不明白它是如何产生的或如何摆脱它。它显示以下位置:

==51957== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==51957==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck- 
amd64-linux.so)
==51957==    by 0x420959: insert_at_last (sllother.c:110)
==51957==    by 0x4218C6: create_linked_list (sllother.c:102)
==51957==    by 0x4206F7: main (sllother.c:35)

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

struct linked_list
{
    int number;
    struct linked_list *next;
};

typedef struct linked_list node;
node *head=NULL, *last=NULL;

void create_linked_list();
void print_linked_list();
void insert_at_last(int value);
void insert_at_first(int value);
void insert_after(int key, int value);
void delete_item(int value);
void search_item(int value);

int main()
{
    int key, value;

    //Create a linked list
    printf("Create Linked List\n");
    create_linked_list();
    print_linked_list();


    //Insert value at last position to existing Linked List
    printf("\nInsert new item at last\n");
    scanf("%d", &value);
    insert_at_last(value);
    print_linked_list();


    //Insert value at first position to existing Linked List
    printf("\nInsert new item at first\n");
    scanf("%d", &value);
    insert_at_first(value);
    print_linked_list();


    //Insert value after a defined value to existing Linked List
    printf("\nEnter a KEY (existing item of List), after that you want to insert a value\n");
    scanf("%d", &key);
    printf("\nInsert new item after %d KEY\n", key);
    scanf("%d", &value);
    insert_after(key, value);
    print_linked_list();


    //Search an item from Linked List
    printf("\nEnter an item to search it from List\n");
    scanf("%d", &value);
    search_item(value);


    //Delete value from List
    printf("\nEnter a value, which you want to delete from list\n");
    scanf("%d", &value);
    delete_item(value);
    print_linked_list();


    return 0;
}


/*
    User Defined Functions
*/
void create_linked_list()
{
    int val;

    while(1)
    {
        printf("Input a number. (Enter -1 to exit)\n");

        scanf("%d", &val);

        if(val==-1)
            break;

        insert_at_last(val);
    }

}


void insert_at_last(int value)
{
    node *temp_node;
    temp_node = (node *) malloc(sizeof(node));

    temp_node->number=value;
    temp_node->next=NULL;

    //For the 1st element
    if(head==NULL)
    {
        head=temp_node;
        last=temp_node;
    }
    else
    {
        last->next=temp_node;
        last=temp_node;
    }

}


void insert_at_first(int value)
{
    node *temp_node = (node *) malloc(sizeof(node));

    temp_node->number=value;
    temp_node->next = head;

    head = temp_node;
}

void insert_after(int key, int value)
{
    node *myNode = head;
    int flag = 0;

    while(myNode!=NULL)
    {
        if(myNode->number==key)
        {
            node *newNode = (node *) malloc(sizeof(node));
            newNode->number = value;
            newNode->next = myNode->next;
            myNode->next = newNode;

            printf("%d is inserted after %d\n", value, key);

            flag = 1;

            break;
        }
        else
            myNode = myNode->next;
    }

    if(flag==0)
        printf("Key not found!\n");

}


void delete_item(int value)
{
    node *myNode = head, *previous=NULL;
    int flag = 0;

    while(myNode!=NULL)
    {
        if(myNode->number==value)
        {
            if(previous==NULL)
                head = myNode->next;
            else
                previous->next = myNode->next;

            printf("%d is deleted from list\n", value);

            flag = 1;
            break;
        }

        previous = myNode;
        myNode = myNode->next;
    }

    if(flag==0)
        printf("Key not found!\n");
}


void search_item(int value)
{
    node *searchNode = head;
    int flag = 0;

    while(searchNode!=NULL)
    {
        if(searchNode->number==value)
        {
            printf("%d is present in this list. Memory address is %d\n", value, searchNode);
            flag = 1;
            break;
        }
        else
            searchNode = searchNode->next;
    }

    if(flag==0)
        printf("Item not found\n");

}


void print_linked_list()
{
    printf("\nYour full linked list is\n");

    node *myList;
    myList = head;

    while(myList!=NULL)
    {
        printf("%d ", myList->number);

        myList = myList->next;
    }
    puts("");
}

我在 main() 中的 Return Zero 之前添加了以下代码,因为作者在代码中没有任何内容来释放内存。

// Free memory
node *ptr = head;
while (ptr != NULL)
{
    node *next = ptr->next;
    free(ptr);
    ptr = next;
}

谢谢

最佳答案

问题出在删除代码void delete_item(int value)中。当找到该值时,该函数会泄漏正在删除的节点:

void delete_item(int value) {
    node *myNode = head, *previous=NULL;
    int flag = 0;
    while(myNode!=NULL) {
        if(myNode->number==value) {
            if(previous==NULL)
                head = myNode->next;
            else
                previous->next = myNode->next;

            printf("%d is deleted from list\n", value);
            flag = 1;
            break;
        }
        previous = myNode;
        myNode = myNode->next;
    }
    if(flag==0)
        printf("Key not found!\n");
}

如您所见,此函数缺少对 free 的调用。您可以通过在 break 之前添加对 free(myNode) 的调用来解决此问题。

关于c - 不明白 Valgrind 中内存泄漏显示的来源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51909302/

相关文章:

c - C中函数指针在数据结构开发中的使用

memory-leaks - Valgrind 和 CUDA : Are reported leaks real?

c++ - 为什么 C 风格的代码比 C++ 风格的代码更快

c - gcc编译的程序运行速度比g++编译的快

c - 中缀到后缀 C 程序

java - 处理 TreeSet 中的重复项

c - ld : _start not found defaulting to

c - 如何避免多线程

c - 如何抑制来自 gpgme 的 valgrind 警告?

c - 出现在 C 数组末尾的随机字符