heat-use-after-free : 访问堆上已经被释放的内存地址
现象:同样代码在LeetCode上报错,但是自己在IDE手动打印并不会报错
个人猜测,这个bug可能来源于LeetCode后台输出打印链表的代码逻辑问题。
问题描述
题目来自LeetCode的86.链表分隔
运行如下代码时,发生报错
/**
* 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* partition(ListNode* head, int x) {
cout << "dfddf" << endl;
ListNode* head_s = new ListNode(-1), *p_s = head_s;
ListNode* head_g = new ListNode(-1), *p_g = head_g;
p_g = head_g;
cout << "fdfdfdf" << endl;
while (head != nullptr){
if (head -> val < x){
p_s -> next = head;
p_s = p_s -> next;
}
else{
p_g -> next = head;
p_g = p_g -> next;
}
head = head -> next;
}
p_s -> next = head_g -> next;
return head_s -> next;
}
};
问题解释
打印日志debug了半天也没知其然,于是上网搜了一圈,基本说的都是链表问题当中使用delete会在LeetCode平台上发生这个问题。还有一个直接说是指针指向了自己,也没给出个解决方法。
偶然在stackoverflow上看到了一个相似的问题
也就是说没有正确的结束链表,就像上面图那样链表末尾并没有结束而又连回来到了中间某个节点上,而我猜测LeetCode给一个链表头打印出链表的代码是打印完一个节点后就自动帮你把节点给释放掉了,而你链表末尾又指向了之前已被释放的节点。
解决方法
在链表结尾指向nullptr
p_g -> next = nullptr;