LeetCode为什么会给出错误:AddressSanitizer:堆缓冲区溢出?

时间:2019-07-17 03:46:27

标签: c++ sorting c++11 c++14 quicksort

我正在用C ++在LeetCode上练习一种简单的快速排序算法。该代码应读取未排序的输入数组并显示其排序版本。快速排序算法使用随机枢轴来确保阵列中的对称性。当我在本地计算机(MinGW Compiler)上运行时,代码本身似乎没有任何问题。但是,当我在LeetCode上运行相同的代码时,会收到全面的错误消息。

下面显示的代码:

 class Solution {
   public:
    vector<int>& sortArray(vector<int>& nums) {
        size_t l = 0;
        size_t r = nums.size();
        quick_sort(nums, l, r);
        return nums;
    }

    void quick_sort(vector<int>& nums, size_t l, size_t r) {
        if (l >= r)
            return;
        size_t pivot = l + rand() % (r - l + 1);
        swap(nums[l], nums[pivot]);
        size_t m = partition(nums, l, r);
        quick_sort(nums, l, m - 1);
        quick_sort(nums, m + 1, r);        
    }

    size_t partition(vector<int>& nums, size_t l, size_t r) {
        size_t j = l;
        int x = nums[l];
        for (size_t i = l + 1; i <= r; i++) {
            if (nums[i] <= x) {
                j++;
                swap(nums[i], nums[j]);
            }
        }
        swap(nums[l], nums[j]);
        return j;
    }
 };

 int main() {
    int n;
    std::cin >> n;
    vector<int> a(n);
    for (auto &item : a) {
        std::cin >> item;
    }
    Solution sorter;
    sorter.sortArray(a);
    for (auto &item : a) {
        std::cout << item << ' ';
    }
}

错误消息如下所示:

==29==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000060 at pc 0x00000040f1a0 bp 0x7ffe8b2e2470 sp 0x7ffe8b2e2468
READ of size 4 at 0x602000000060 thread T0
    #1 0x7f7f30fcf2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)

0x602000000060 is located 0 bytes to the right of 16-byte region [0x602000000050,0x602000000060)
allocated by thread T0 here:
#0 0x7f7f329f4ce0 in operator new(unsigned long) (/usr/local/lib64/libasan.so.5+0xe9ce0)
#4 0x7f7f30fcf2e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)

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 00 00[fa]fa fa fa
  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
==29==ABORTING

1 个答案:

答案 0 :(得分:1)

在@ igor-tandenik的评论中添加

sortArray(vector<int>& nums)中:

size_t r = nums.size();
quick_sort(nums, l, r);

quick_sort(vector<int>& nums, size_t l, size_t r)中:

size_t m = partition(nums, l, r);

partition(vector<int>& nums, size_t l, size_t r)中:

for (size_t i = l + 1; i <= r; i++) {
    if (nums[i] <= x) {
        j++;
        swap(nums[i], nums[j]);
    }
}

由于循环条件为i <= r,因此i将为nums.size() 因此swap(nums[i], nums[j])无效。