LeetCode 206反转链表代码出现heap-use-after-free错误求助
LeetCode 206. Reverse Linked List 堆使用后释放错误分析
在解决LeetCode 206. Reverse Linked List(给定单链表的head节点,反转该链表并返回反转后的链表)问题时,编写了如下代码:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { vector<ListNode*> addrs; ListNode* cur=head; if(cur==NULL||cur->next==NULL) return cur; // storing all addrs in sequence while(cur!=NULL) { addrs.push_back(cur); cur=cur->next; } // reversing process for(int i=addrs.size()-1;i>0;i--) { addrs[i]->next=addrs[i-1]; } return addrs[addrs.size()-1]; } };
测试时触发错误:
ERROR: AddressSanitizer: heap-use-after-free
错误原因分析
错误和vector无关,核心问题是反转后未处理原链表头节点的next指针:
- 反转操作仅设置了从最后一个节点到第二个节点的
next指向,但原链表的头节点(即addrs[0])的next仍指向原第二个节点,导致链表形成循环引用。比如原链表为1->2->3,反转后变为3->2->1,但1的next还是指向2,最终链表成了3->2->1->2->...的环。 - LeetCode的测试框架在遍历或回收链表内存时,会因循环引用出现无限遍历或重复访问已释放内存的情况,触发AddressSanitizer的
heap-use-after-free报错。
修复方案
在反转循环结束后,添加一行代码将原头节点的next置空,断开环结构:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode() : val(0), next(nullptr) {} * ListNode(int x) : val(x), next(nullptr) {} * ListNode(int x, ListNode *next) : val(x), next(next) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { vector<ListNode*> addrs; ListNode* cur=head; if(cur==NULL||cur->next==NULL) return cur; // storing all addrs in sequence while(cur!=NULL) { addrs.push_back(cur); cur=cur->next; } // reversing process for(int i=addrs.size()-1;i>0;i--) { addrs[i]->next=addrs[i-1]; } // 断开原头节点的next,避免循环引用 addrs[0]->next = nullptr; return addrs[addrs.size()-1]; } };
内容的提问来源于stack exchange,提问作者Daniel Cha
相关产品推荐
相关产品推荐

