滑动窗口最大值C++代码报错:AddressSanitizer堆缓冲区溢出排查
滑动窗口最大值问题的堆溢出错误排查与修复
问题背景
给定整数数组nums和大小为k的滑动窗口,窗口从数组最左端移动到最右端,每次右移一位,计算每个窗口内的最大值。输入示例:nums = [1,3,-1,-3,5,3,6,7],k = 3;预期输出:[3,3,5,5,6,7]。
提供的实现代码运行时触发堆缓冲区溢出错误,报错信息如下:
================================================================= ==31==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000090 at pc 0x000000345e1e bp 0x7ffef610bff0 sp 0x7ffef610bfe8 READ of size 4 at 0x603000000090 thread T0 #2 0x7fb1bb36d0b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 0x603000000090 is located 0 bytes to the right of 32-byte region [0x603000000070,0x603000000090) allocated by thread T0 here: #6 0x7fb1bb36d0b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) Shadow bytes around the buggy address: 0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff8000: fa fa 00 00 00 07 fa fa fd fd fd fa fa fa 00 00 =>0x0c067fff8010: 00 00[fa]fa 00 00 00 00 fa fa fa fa fa fa fa fa 0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8060: 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 ==31==ABORTING
错误原因
- 外层循环范围越界:原代码外层循环
for(int i=0; i<n; i++)遍历数组所有元素,但滑动窗口的有效起始位置仅到n-k,超出后窗口会超出数组边界。 - 内层循环起始索引错误:原代码内层循环从
j=1开始,跳过了窗口的第一个元素,同时当i+k超过数组长度时,j会访问数组外的内存,直接触发堆溢出。 - 后处理逻辑冗余无效:先错误生成过多元素再截断,无法从根源避免越界访问,还降低了代码效率。
修复后的代码
class Solution { public: vector<int> maxSlidingWindow(vector<int> &nums, int k) { int n = nums.size(); vector<int> answer; // 仅遍历有效窗口的起始位置 for(int i = 0; i <= n - k; i++){ int mx = INT_MIN; // 遍历当前窗口内的所有元素 for(int j = i; j < i + k; j++){ mx = max(mx, nums[j]); } answer.push_back(mx); } return answer; } };
修复说明
- 调整外层循环条件为
i <= n - k,确保每个窗口完全包含在数组范围内,避免越界。 - 内层循环从
j=i开始,遍历窗口内的所有元素(i到i+k-1),既不遗漏元素,也不访问数组外内存。 - 移除冗余的后处理截断逻辑,直接生成正确数量的结果元素,提升代码效率。
内容的提问来源于stack exchange,提问作者joy
相关产品推荐
相关产品推荐

