Rasputin
Rasputin

Reputation: 41

Malloc and free in linkedlist recursion function

I know that for every malloc there must be a free(), but in case of an existing linkedlist passed in a recursive function to insert a new node inside the linkedlist how would you free that? I'm using valgrind and it shows me that i must free the malloc

So my function has as parameters a char * and the pointer to the list passed as **, I did some research and it was needed to be passed like this in order to get the new nodes inserted even tho a pointer only worked well

void showDir(char *name, linkedList **list) {
    DIR *dir;
    struct dirent *entry;

    if (!(dir = opendir(name))) return;

    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_type == DT_DIR) {
            char path[1024];
            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;
            snprintf(path, sizeof(path), "%s/%s", name, entry->d_name);
            showDir(path, list);
        }
        linkedList *node = malloc(sizeof(linkedList));
        if (!node) {
            printf("Error!");
        }
        node->next = NULL;
        char filePath[1024];
        snprintf(filePath, sizeof(filePath), "%s/%s", name, entry->d_name);
        node->path = malloc(strlen(filePath) + 1);
        strcpy(node->path, filePath);
        if (*list) {
            int found = 0;
            for (linkedList *ptr = *list; ptr != NULL; ptr = ptr->next) {
                if (strcmp(ptr->path, filePath) == 0) {
                    found = 1;
                }
                if (ptr->next == NULL && found == 0) {
                    ptr->next = node;
                    break;
                }
            }
        } else {
            *list = node;
        }
    }
    closedir(dir);
}

I'm calling the recursive function like this showDir(ptr->path, &list); and freeing it like this

linkedList *ptr = list;
    while (ptr != NULL) {
        linkedList *next = ptr->next;
        free(ptr->path);
        free(ptr);
        ptr = next;
    }

Of course the list passed in the initial call is already filled up!

Thanks for the reading and hope you can help to understand what I'm doing wrong in here!

--EDIT

==1914== 64 (24 direct, 40 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 14
==1914==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==1914==    by 0x10A633: showDir(filestat.c:512)
==1914==    by 0x10A629: showDir(filestat.c:510)
==1914==    by 0x10A629: showDir(filestat.c:510)
==1914==    by 0x109581: main (filestat.c:186)

Upvotes: 1

Views: 2443

Answers (2)

dreamcrash
dreamcrash

Reputation: 51463

To free a Linkedlist recursively you can do it as follows:

void freeList(struct node* head){
    if(head != NULL){
      freeList(head->next);
      free(head);
    }
}

Upvotes: 1

Alan Barrett II
Alan Barrett II

Reputation: 65

Create a tmp pointer. This way as you free them you can still move though the struct.

If you don't create a temp pointer to the address of the struct you are losing access to the rest of the nodes.

    void freeList(struct node* head)
{
   struct node* tmp;

   while (head != NULL)
    {
       tmp = head;
       head = head->next;
       free(tmp);
    }

}

C: How to free nodes in the linked list?

Upvotes: 1

Related Questions