C语言返回动态分配数组时出现Heap-buffer-overflow运行时错误求助
排查C语言Heap-buffer-overflow错误:数组拼接函数问题
我刚开始学习C语言编程,在实现数组拼接(返回nums数组的两次拼接结果)时遇到了Heap-buffer-overflow运行时错误。
初始代码
int* getConcatenation(int* nums, int numsSize, int* returnSize){ int *ans; ans=(int*)malloc(numsSize * sizeof(int)); for (int i=0;i<numsSize;i++){ ans[i]=nums[i]; ans[i+numsSize]=nums[i]; } free(ans); return ans; }
错误信息
AddressSanitizer: heap-buffer-overflow on address 0x60200000003c at pc 0x55780cb25d30 bp 0x7ffd83067af0 sp 0x7ffd83067ae0 WRITE of size 4 at 0x60200000003c thread T0 #2 0x7fabeed390b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 0x60200000003c is located 0 bytes to the right of 12-byte region [0x602000000030,0x60200000003c) allocated by thread T0 here: #0 0x7fabef97ebc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8) #3 0x7fabeed390b2 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 00 04 fa fa 00[04]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 ==44==ABORTING
修改后仍有问题的代码
int* getConcatenation(int* nums, int numsSize, int* returnSize) { int *ans; ans=malloc(2*numsSize * sizeof(int)); for (int i=0;i<numsSize;i++) { ans[i]=nums[i]; ans[i+numsSize]=nums[i]; } return ans; }
错误排查与修复
初始代码的两个核心错误
- 内存分配不足:只分配了
numsSize * sizeof(int)的空间,但循环中要写入ans[i+numsSize],需要2倍的空间,直接导致堆缓冲区溢出。 - 返回野指针:在返回前调用了
free(ans),释放了堆内存,此时返回的指针指向已释放的区域,属于use-after-free错误,后续访问会触发未定义行为。
修改后代码的遗漏点
修改后的代码虽然修复了内存分配的问题,但没有设置*returnSize的值。这个参数的作用是告诉调用者返回数组的长度,如果不设置,调用者可能会误以为数组长度是numsSize或者其他值,从而访问超出数组实际范围的元素,同样会触发Heap-buffer-overflow错误。
正确的代码实现
int* getConcatenation(int* nums, int numsSize, int* returnSize){ // 分配2倍原数组大小的内存 int *ans = malloc(2 * numsSize * sizeof(int)); if (ans == NULL) { // 内存分配失败的处理,避免空指针访问 *returnSize = 0; return NULL; } // 填充数组:前半部分和后半部分都复制原数组内容 for (int i = 0; i < numsSize; i++) { ans[i] = nums[i]; ans[i + numsSize] = nums[i]; } // 告诉调用者返回数组的长度是原数组的2倍 *returnSize = 2 * numsSize; return ans; }
内容的提问来源于stack exchange,提问作者user20977916
相关产品推荐
相关产品推荐

