You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确释放含子链表的Linked List内存并解决打印残留问题?

问题解决:释放嵌套链表内存并避免非法访问

问题根源分析

  • 释放Item时,先执行free(item)再访问temp->next,此时temp指向的内存已被系统回收,属于未定义行为,会导致后续指针遍历逻辑错乱
  • 释放List节点时,同样先free(list_ptr)再访问templis->next,也是未定义行为
  • 内存释放完成后,原链表头指针未被置为NULL,print_list仍能通过该指针遍历已释放的内存地址,读取到垃圾值
  • print_list存在打印错误:printf("\t%s\n", item)应打印item->name,而非item指针本身

修正后的代码

1. 修正free_lists函数

将参数改为List**,确保能修改外部的链表头指针,同时调整释放顺序,避免访问已释放内存:

void free_lists(List **board)
{
    List *list_ptr = *board;
    while (list_ptr != NULL)
    {
        // 释放当前List下的所有Item节点
        Item *item = list_ptr->first_item;
        while (item != NULL)
        {
            Item *temp_item = item->next; // 先保存下一个Item的指针
            free(item);
            item = temp_item;
        }

        // 释放当前List节点
        List *temp_list = list_ptr->next; // 先保存下一个List的指针
        free(list_ptr);
        list_ptr = temp_list;
    }
    *board = NULL; // 将外部链表头指针置空,彻底阻断非法访问
}

2. 修正print_list函数

修复Item打印的错误:

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->name); // 改为打印item的name字段
            item = item->next;
        }
        list_ptr = list_ptr->next;
    }
    printf("Press any key to continue...\n");
    getch();
    system("cls");
}

使用说明

调用free_lists时,需传入链表头指针的地址:

// 假设board是List*类型的链表头指针
free_lists(&board);

此时board会被置为NULL,后续调用print_list(board)时,while(list_ptr != NULL)条件直接不成立,不会输出任何内容,彻底避免访问已释放的内存。

内容的提问来源于stack exchange,提问作者Mohammad Aslam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:17:03