You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:25:13