I am learning c++ right now, trying to solve 239. Sliding Window Maximum on Leetcode. Keep encountering ERROR: AddressSanitizer: heap-use-after-free
even though I have never used free()
anywhere in my code. What could be the problem here?
My code:
#include <vector>
#include <deque>
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if (k == 1) {
return nums;
}
deque<int> q = {nums[k-1]};
deque<int> qi = {k-1};
for (int i = k-2; i >= 0; i--) {
if (nums[i] > q.front()) {
q.push_front(nums[i]);
qi.push_front(i);
}
}
vector<int> output = {q.front()};
for (int i = k; i < nums.size(); i++) {
if (qi.front() < i - k + 1) {
q.pop_front();
qi.pop_front();
}
if (q.size() > 0) {
while (q.back() <= nums[i]) {
q.pop_back();
qi.pop_back();
}
}
q.push_back(nums[i]);
qi.push_back(i);
output.push_back(q.front());
}
return output;
}
};
Full error message:
=================================================================
==23==ERROR: AddressSanitizer: heap-use-after-free on address 0x6150000009fc at pc 0x000000356a92 bp 0x7ffd9138ecb0 sp 0x7ffd9138eca8
READ of size 4 at 0x6150000009fc thread T0
#2 0x7f1796504082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
0x6150000009fc is located 508 bytes inside of 512-byte region [0x615000000800,0x615000000a00)
freed by thread T0 here:
#4 0x7f1796504082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
previously allocated by thread T0 here:
#4 0x7f1796504082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
Shadow bytes around the buggy address:
0x0c2a7fff80e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c2a7fff80f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2a7fff8100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fff8110: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fff8120: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c2a7fff8130: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]
0x0c2a7fff8140: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2a7fff8150: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fff8160: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fff8170: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2a7fff8180: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
==23==ABORTING
So the error occurs when q.back()
tries to access the last element of q
when q
is empty. After I changed this part of the code:
if (q.size() > 0) {
while (q.back() <= nums[i]) {
q.pop_back();
qi.pop_back();
}
}
to this:
while (!q.empty()) {
if (q.back() <= nums[i]) {
q.pop_back();
qi.pop_back();
} else {
break;
}
}
the problem is resolved.