Mohammad Aslam
Mohammad Aslam

Reputation: 3

Freeing memory of Linked list (which also contains another Linked list)

Basically I want to be able to free memory of a linked list (which also contains a linked list), so that the user can enter their own custom values to create a new linked list. I also want my print function to no longer find these values in memory once they have been freed, so maybe the condition (while list_ptr != NULL) is not the correct condition to use while printing? I have the two following structs:

typedef struct item
{
    char name[125];
    struct item *next;
} Item;


typedef struct list
{
    char name[125];
    struct list *next;
    struct list *prev;
    Item *first_item;
} List;

I used them to create a linked list using the following function, which loads my default list:

void load_default(List **board)
{

    List *list1 = malloc(sizeof(List));
    strcpy(list1->name, "Abey:");
    list1->next = NULL;
    Item *item1_1 = malloc(sizeof(Item));
    strcpy(item1_1->name, "Oculus Pro");
    Item *item1_2 = malloc(sizeof(Item));
    strcpy(item1_2->name, "Oculus Quest 1");
    item1_2->next = NULL;
    list1->first_item = item1_1;
    item1_1->next = item1_2;
    List *list2 = malloc(sizeof(List));
    strcpy(list2->name, "Dante:");
    list2->next = list1;
    Item *item2_1 = malloc(sizeof(Item));
    strcpy(item2_1->name, "Oculus Quest 1");
    item2_1->next = NULL;
    Item *item2_2 = malloc(sizeof(Item));
    strcpy(item2_2->name, "3070 RTX");
    item2_2->next = NULL;
    list2->first_item = item2_1;
    item2_1->next = item2_2;
    List *list3 = malloc(sizeof(List));
    strcpy(list3->name, "Tim:");
    list3->next = list2;
    Item *item3_1 = malloc(sizeof(Item));
    strcpy(item3_1->name, "Oculus Quest 2");
    list3->first_item = item3_1;
    item3_1->next = NULL;
    List *list4 = malloc(sizeof(List));
    strcpy(list4->name, "Nick:");
    Item *item4_1 = malloc(sizeof(Item));
    strcpy(item4_1->name, "3070 RTX");
    item4_1->next = NULL;
    list4->first_item = item4_1;
    list4->next = list3;
    list1->prev = list2;
    list2->prev = list3;
    list3->prev = list4;
    list4->prev = NULL;
    *board = list4;
}

I also have a print function:

void print_list(List *list)
{
    List *list_ptr = list;

    while (list_ptr != NULL)
    {
        printf("%s\n", list_ptr->name);
        Item *item = list_ptr->first_item;
        while (item != NULL)
        {
            printf("\t%s\n", item);
            item = item->next;
        }
        list_ptr = list_ptr->next;
    }
    printf("Press any key to continue...\n");
    getch();
    system("cls");
}

I tried to create a function to free memory but it did not work as expected:

void free_lists(List *list)
{
    List *list_ptr = list;
    Item *item;
    while (list_ptr != NULL)
    {
        item = list_ptr->first_item;
        while (item != NULL)
        {
            Item *temp = item;
            free(item);
            item = temp->next;
        }
        List *templis = list_ptr;
        free(list_ptr);
        list_ptr = templis->next;
    }
}

While it did free up some bits, I was left with the following:

p8w
         p♫w
p8w
         p8w
p8w
         p8w
         3070 RTX
p8w
         p8w
         Oculus Quest 1

when i called the print function. Somehow my print function is still finding all the elements, but finding garbage values, or the original values, in those parts of memory.

Upvotes: 0

Views: 36

Answers (1)

alex01011
alex01011

Reputation: 1702

In these lines,

        while (item != NULL)
        {
            Item *temp = item;
            free(item);
            item = temp->next;
        }

temp points to item by you have previously destroyed whatever item was pointing to.

Instead, it should point to item->next.

        while (item != NULL)
        {
            Item *temp = item->next;
            free(item);
            item = temp;
        }

Same goes for the outer loop.

Aside, code will also benefit from an insert function.

Upvotes: 0

Related Questions