简体   繁体   English

C内存泄漏,哪里没有内存泄漏? (瓦尔格林德)

[英]C memory leak, where there is no memory leak? (valgrind)

valgrind is telling me that a specific line in my code creates a memory leak, but when looking at that line, it does not seem to even be able to create one. valgrind 告诉我代码中的特定行会造成内存泄漏,但是在查看该行时,它似乎甚至无法创建内存泄漏。

I am working with this pretty simple Linked List struct list.h:我正在使用这个非常简单的链表结构 list.h:

typedef struct _linekd_list{
    void* object;
    struct _linked_list* next;
}linked_list;

And this is how a list is initialized in list.c:这就是在 list.c 中初始化列表的方式:

linked_list* newlist(){
    linked_list * list = malloc(sizeof(linked_list));
    list->next = NULL;  //As a flag, that there is no next element
    list->object = NULL;
    return list;
}

My queue works so, that the first object of the first linked_list is always NULL, the first object is stored in the next linked_list.我的队列如此工作,第一个linked_list 的第一个对象始终为NULL,第一个对象存储在下一个linked_list 中。

Now here is where the memory leak occurs:现在这里是发生内存泄漏的地方:

int list_add(void* new_object, linked_list* list){
        while(list->next != NULL) {  //First go to the end of the queue
            list = list->next;
        }
        list->next = malloc(sizeof(linked_list)); //Vangrind says there is a leak
        list->next->next = NULL; //Set the next list-object to NULL (acts like a flag)
        list->next->object = new_object; //And now store the pointer of the actual object
        if(list->next->object == new_object) {
            return 0;
        } else {
            return 1;
        }
    return 0;
}

This is what valgrind tells me:这就是 valgrind 告诉我的:

==33369== 16 bytes in 1 blocks are definitely lost in loss record 1 of 3
==33369==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==33369==    by 0x402219: list_add (list.c:11)
==33369==    by 0x4012D0: main (test_list.c:38)
==33369== 

Here is the function that recursively frees the list (no memory leak detected):这是递归释放列表的函数(未检测到内存泄漏):

void free_list(linked_list* list){
    if(list->next != NULL) {
        free_list(list->next);
        free(list);
    }
}

You don't free the last node in the list.您不会释放列表中的最后一个节点。

free_list does nothing if list->next is NULL .如果list->nextNULLfree_list什么也不做。 But you don't want to do nothing.但你不想什么都不做。 You want to not recurse, but you still need to free the node.你不想递归,但你仍然需要释放节点。 So move the call to free out of the conditional, or change the test to check whether list itself is NULL所以将调用从条件中free ,或者更改测试以检查list本身是否为NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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