面试题 02.06 cpp 报错AddressSanitizer: heap-use-after-free, 求解
11671
2020.06.10
发布于 未知归属地

判断回文链表, 题目链接

我本来的思路是, 对于 1 2 2 1 ,对后半部分翻转链表, 换成两个链表1 2 null1 2 2 null 然后比较
对于1 2 3 2 1 同理1 2 3 null1 2 3 null

通过的代码如下

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next) return true;
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next){
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode *pre = slow, *cur = slow->next;
        slow->next = nullptr;
        while(cur){
            ListNode *tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }

        bool res = true;

        while (pre && head && res){
            if (pre->val != head->val) res = false;
            pre = pre->next;
            head = head->next;
        }
        return res;
    }
};

开始的时候, 我逻辑写错了, 没有写slow->next = nullptr , 这样操作, 两个链表应该是 [1 2 2 2 2 2 ...] 这样, 我感觉应该是会死循环下去, 但是 leetcdoe 抛出的错误是 heap-use-after-free

对应代码和报错信息如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(!head || !head->next) return true;
        ListNode *slow = head, *fast = head;
        while (fast->next && fast->next->next){
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode *pre = slow, *cur = slow->next;
        // slow->next = nullptr;
        while(cur){
            ListNode *tmp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = tmp;
        }

        bool res = true;

        while (pre && head && res){
            if (pre->val != head->val) res = false;
            pre = pre->next;
            head = head->next;
        }
        return res;
    }
};
=================================================================
==45==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000058 at pc 0x0000003f3d3d bp 0x7ffda14f1260 sp 0x7ffda14f1258
READ of size 8 at 0x602000000058 thread T0
    #2 0x7f3df45df82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x602000000058 is located 8 bytes inside of 16-byte region [0x602000000050,0x602000000060)
freed by thread T0 here:
    #3 0x7f3df45df82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
previously allocated by thread T0 here:
    #4 0x7f3df45df82f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa fd fa fa fa fd fa fa fa fd[fd]fa fa fd fd
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==45==ABORTING

想请教下这个错是编译器怎么查出来的, 为什么会出现这种错误?

评论 (5)