如何正确释放含子链表的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
相关产品推荐
相关产品推荐

