1

I have now been struggling for this problem for hours and searched a lot on the web but could not find a solution.

I created a linked list struct which has a struct node as head. Now I want to split my linked list at a specific given node, returning the second list.

Code:

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;
            }
        }

This code seemed to work for me, it makes the node next to the given node the head for list 2. But this is not working out for me, I'm having memoryleaks when testing:

Testing code (all other functions are working correctly):

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

Error of memory leak:

==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).

Clean up code:

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;
            }


        }
Stylo
  • 250
  • 1
  • 4
  • 12

1 Answers1

0

list_cut_after returns a pointer to the new list, but you aren't saving it. This means the memory is lost and you have a leak.

Save the return value of this function, then later clean up the returned list.

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

list_cleanup(l);
list_cleanup(l2);
dbush
  • 205,898
  • 23
  • 218
  • 273