释放链表(也包含另一个链表)的内存

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

提问人:Mohammad Aslam 提问时间:4/3/2023 更新时间:4/3/2023 访问量:34

问:

基本上,我希望能够释放链表(其中还包含链表)的内存,以便用户可以输入自己的自定义值来创建新的链表。我还希望我的打印函数在释放这些值后不再在内存中找到这些值,所以条件(list_ptr != NULL 时)可能不是打印时使用的正确条件? 我有以下两个结构:

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;

我使用它们通过以下函数创建链表,该函数加载我的默认列表:

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

我还有一个打印功能:

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

我试图创建一个函数来释放内存,但它没有按预期工作:

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

虽然它确实释放了一些内容,但我只剩下以下内容:

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

当我调用打印函数时。不知何故,我的打印函数仍在查找所有元素,但在内存的这些部分查找垃圾值或原始值。

c 链接列表 malloc free

评论

0赞 Fe2O3 4/3/2023
在块被释放后使用(“取消引用”)指向动态内存的指针是未定义的......别这样。

答:

0赞 alex01011 4/3/2023 #1

在这些行中,

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

temp你之前已经摧毁了所指向的任何东西。itemitem

相反,它应该指向 。item->next

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

外循环也是如此。

除此之外,代码也将从函数中受益。insert

评论

0赞 Mohammad Aslam 4/4/2023
我做了如下更改: ''' void free_lists(List *list) { if (list == NULL) { printf(“List is empty\n”); return; } else { while (list != NULL) { List *temp = list->next;项目 *item = list->first_item;while (item != NULL) { item *temp = item->next; free(item); item = temp; } free(list);列表 = temp;} } } ''' 但是,它并没有解决问题。
0赞 alex01011 4/4/2023
@MohammadAslam 您是如何确定它没有解决问题的?
0赞 alex01011 4/4/2023
也许您再次尝试打印,但您期望什么都显示不出来?如果是这种情况,则行为是未定义的,换句话说,您可能会获得以前存储的项目,或者可能会遇到错误,或者可能会收到完全意外的内容。
0赞 Mohammad Aslam 4/4/2023
你是对的,我现在对函数进行了更多的更改,以便我可以修改指针,现在在我释放内存后,我也将该指针设置为 NULL,现在我的打印函数不打印任何内容。感谢您的帮助!