LeetCode 2487代码中delete curr引发heap-use-after-free错误原因排查
解决LeetCode 2487时的堆内存重复释放问题
问题背景
我在解决LeetCode 2487《移除链表中的节点》问题时,采用的C++解法思路是:先反转链表,移除左侧(对应原链表右侧)存在更大值的节点,最后再次反转链表。但代码仅在注释掉delete curr;时能通过所有测试用例;取消注释该行就会触发AddressSanitizer: heap-use-after-free error。
相关代码
class Solution { public: ListNode* reverseList(ListNode* head) { ListNode* prev = nullptr; ListNode* curr = head; while (curr) { ListNode* next = curr->next; curr->next = prev; prev = curr; curr = next; } return prev; } ListNode* removeNodes(ListNode* head) { head = reverseList(head); int curMax = INT_MIN; ListNode dummy(0); dummy.next = head; ListNode* prev = &dummy; ListNode* curr = head; while (curr) { if (curr->val < curMax) { ListNode* temp = curr->next; prev->next = curr->next; // delete curr; // 取消注释该行会崩溃 curr = temp; } else { curMax = max(curMax, curr->val); prev = curr; curr = curr->next; } } return reverseList(dummy.next);; } };
我原本的写法是:
if (curr->val < curMax) { prev->next = curr->next; delete curr; curr = prev->next; }
错误原因分析
查看错误日志可知,问题出在LeetCode测试框架的__ListNodeUtils__::freeList函数中:
SUMMARY: AddressSanitizer: heap-use-after-free (solution+0x1aa425) in __ListNodeUtils__::freeList(ListNode*&)
本质原因是同一个节点被重复释放:
- LeetCode的测试框架会负责创建输入链表,并且在你的函数执行完毕后,自动遍历并释放输入链表和输出链表的所有节点内存。
- 如果你在函数内部手动
delete了某些输入链表的节点,测试框架后续尝试再次释放这些节点时,就会触发堆内存重复释放的错误。
解决方法
在LeetCode的题目场景下,不需要手动释放节点内存。你只需要调整链表的指针指向,构建出符合要求的链表结构即可,内存管理完全由测试框架负责。
直接注释掉所有delete相关代码,就能避免和测试框架的内存释放逻辑冲突,同时保证功能正确。
修正后可运行代码
class Solution { public: ListNode* reverseList(ListNode* head) { ListNode* prev = nullptr; ListNode* curr = head; while (curr) { ListNode* next = curr->next; curr->next = prev; prev = curr; curr = next; } return prev; } ListNode* removeNodes(ListNode* head) { head = reverseList(head); int curMax = INT_MIN; ListNode dummy(0); dummy.next = head; ListNode* prev = &dummy; ListNode* curr = head; while (curr) { if (curr->val < curMax) { ListNode* temp = curr->next; prev->next = curr->next; curr = temp; } else { curMax = max(curMax, curr->val); prev = curr; curr = curr->next; } } return reverseList(dummy.next); } };
内容的提问来源于stack exchange,提问作者notSukuna
相关产品推荐
相关产品推荐

