LeetCode实现strStr触发heap-buffer-overflow错误原因咨询
问题背景
该问题对应LeetCode平台的*实现strStr*编程题。本地编译运行自行编写的C语言题解代码可正常执行,但提交到LeetCode平台运行时触发异常报错,无法定位问题根源。
题解实现代码
#include <stdio.h> #include <stdlib.h> int strStr(char *haystack, char *needle) { if (needle[0] == '\0') return 0; int i = 0; int j = 0; while (haystack[i] != '\0') { while (haystack[i] == needle[j] && haystack[i] != '\0' && needle[j] != '\0') { i++; j++; } if (needle[j] == '\0') { return i - j; } else { j = 0; } i++; } return -1; } int main() { printf("%d\n", strStr("aaa", "aaaa")); return 0; }
LeetCode平台报错信息
================================================================= ==32==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000014 at pc 0x5620a8c4472e bp 0x7fff98a004c0 sp 0x7fff98a004b0 READ of size 1 at 0x602000000014 thread T0 #2 0x7fdce2ee00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 0x602000000014 is located 0 bytes to the right of 4-byte region [0x602000000010,0x602000000014) allocated by thread T0 here: #0 0x7fdce3b25bc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8) #3 0x7fdce2ee00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 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[04]fa fa fa 05 fa fa fa fa fa 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 Shadow gap: cc ==32==ABORTING
报错原因说明
该heap-buffer-overflow(堆缓冲区越界读)由代码下标访问逻辑错误导致,具体触发流程:
- 以测试用例
haystack = "aaa"、needle = "aaaa"为例,两个字符串前3个字符完全匹配,内层while循环会连续执行3次i++、j++,执行后i=3(指向haystack的结束符\0,属于合法访问位置),j=3(指向needle的第4个字符'a')。 - 内层循环判断条件顺序存在缺陷:优先判断
haystack[i] == needle[j],再校验字符串是否到达末尾。此时haystack[3]是结束符,和needle[3]的'a'不相等,内层循环退出。代码重置j=0后,执行外层循环逻辑里的i++,i变为4。 - 下一轮外层while循环启动时,首先访问
haystack[4],而"aaa"包含结束符总共仅占4字节内存,合法索引范围是0-3,访问索引4已经超出堆上分配的内存边界,直接触发地址消毒器的越界报错。 - 本地运行未报错是因为本地编译默认未开启地址消毒检测,越界位置的内存值恰好未触发程序崩溃,属于C语言未定义行为的偶然正常表现,不代表代码逻辑正确。
内容的提问来源于stack exchange,提问作者altair00
相关产品推荐
相关产品推荐

