链表切割的内存泄漏

Posted

技术标签:

【中文标题】链表切割的内存泄漏【英文标题】:Memory leak with linked list cut 【发布时间】:2019-07-11 01:36:51 【问题描述】:

我现在已经为这个问题苦苦挣扎了几个小时,在网上搜索了很多,但找不到解决方案。

我创建了一个以结构节点为头的链表结构。 现在我想在特定的给定节点拆分我的链表,返回第二个列表。

代码:

struct list* list_cut_after(struct list* l, struct node* n) 

      if (l && n) 

          if (n->next == NULL)
                struct list *l2 = list_init();
                return l2;
            

               struct list *l2 = list_init();
               l2->head = n->next;
               n->next = NULL;



            
            else 
                return NULL;
            
        

这段代码似乎对我有用,它使给定节点旁边的节点成为列表 2 的头部。但这对我来说不起作用,我在测试时遇到了内存泄漏:

测试代码(所有其他功能都正常工作):

START_TEST (test_cut)

    struct list* l = list_init();
    struct node* n;

    for (int i = 1; i < 6; i++)  
        n = list_new_node(i);
        list_add_back(l, n);
    



    struct node *y = list_get_ith(l, 2);

    list_cut_after(l, y);



    list_cleanup(l);


END_TEST

内存泄漏错误:

==21284==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 8 byte(s) in 1 object(s) allocated from:
    #0 0x7f6a6f792b50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x55de71ac1b01 in list_init /home/bart/Downloads/insertion_sort/list.c:36
    #2 0x55de71ac20a7 in list_cut_after /home/bart/Downloads/insertion_sort/list.c:345
    #3 0x55de71ac16f6 in test_cut /home/bart/Downloads/insertion_sort/check_list.c:395
    #4 0x55de71ac4bb5 in srunner_run (/home/bart/Downloads/insertion_sort/check_list+0x6bb5)

Indirect leak of 48 byte(s) in 3 object(s) allocated from:
    #0 0x7f6a6f792b50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x55de71ac1b39 in list_new_node /home/bart/Downloads/insertion_sort/list.c:51
    #2 0x55de71ac16ad in test_cut /home/bart/Downloads/insertion_sort/check_list.c:387
    #3 0x55de71ac4bb5 in srunner_run (/home/bart/Downloads/insertion_sort/check_list+0x6bb5)

SUMMARY: AddressSanitizer: 56 byte(s) leaked in 4 allocation(s).

清理代码:

int list_unlink_node(struct list* l, struct node* n) 

        if (n != NULL || l != NULL) 
            if (n == l->head)
                l->head = list_next(n);
                n->next = NULL;
                return 0;
            
            else 
                list_prev(l, n)->next = list_next(n);
                n->next = NULL;
                return 0;
            

        
        else 
            return 1;
        

    

    void list_free_node(struct node* n) 
        free(n);

    
        int list_cleanup(struct list* l) 
            if (l)

                struct node *current = list_head(l);
                struct node *next;

                while (current != NULL)
                
                    next = list_next(current);
                    list_unlink_node(l, current);
                    list_free_node(current);
                    current = next;

                
                free(l);
                return 0;
            
            else 
                return 1;
            


        

【问题讨论】:

【参考方案1】:

list_cut_after 返回一个指向新列表的指针,但您没有保存它。这意味着内存丢失并且您有泄漏。

保存此函数的返回值,稍后清理返回的列表。

struct list *l2 = list_cut_after(l, y);

list_cleanup(l);
list_cleanup(l2);

【讨论】:

以上是关于链表切割的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

golang 切片中的内存泄漏

奇怪的容器内存泄漏

是否可以在不使用malloc的情况下进行内存泄漏?

c++ 内存泄漏问题

MFC内存泄漏调试

如何防止java中的内存泄漏