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

调用free(_mult)致程序崩溃,free(_add)正常的C语言问题排查

问题:free(_mult)崩溃但free(_add)正常的原因分析

本人英文不佳,是C语言新手,正在实现2-10进制下两个数的求和与乘法功能。程序输出结果正确,但调用free(_mult)时程序崩溃,调用free(_add)却无异常,对此感到困惑,特附上代码寻求原因:

int * convert(long long int x, int base, int *arr)
// convert the number to base b and return the array with length 64
{
    int i = 63;
    while(x != 0)
    {
        arr[i] = x % base;
    
        x /= base;
        i--;
    }
    for(int j=i; j>=0; j--)     arr[j] = 0;
    return arr;
}

int * add(int *n, int *m, int base, int * arr)
// calculate the summation bit by bit.
{
    int carry = 0, sum;
    int v1, v2;
    for(int i=63; i>=0; i--)
    {
        v1 = n[i];
        v2 = m[i];
    
        sum = v1 + v2 + carry;
        carry = sum / base;
    
        arr[i] = sum % base;
     }

    return arr;
}

int * mult(int *n, int*m, int base, int * arr)
// calculate the multiplication bit by bit.
{   
    for(int i=0; i<64; i++)
        arr[i] = 0;
    int ind_m = 64;
    int index = 64;
    while(ind_m != 0)
    {
        int ind_n = 64;
        int carry = 0;
        int ind_arr, res;
        ind_arr = index - 1 - (64 - ind_m);
        while(ind_n != 0)
        {   
            res = ( m[ind_m-1] * n[ind_n-1] ) + arr[ind_arr] + carry;
            carry = res / base;
        
            arr[ind_arr] = res % base;
    
            ind_arr--;
            ind_n--;
        }
        arr[ind_arr] += carry;
        ind_m--;
    }

    return arr;
}

int main()
{
    int b;
    long long int x, y;
    scanf("%d%lld%lld", &b, &x, &y);

    int *n = malloc(sizeof(int)*(64));//64 bit for digits
    int *m = malloc(sizeof(int)*(64));

    for(int i=0; i<64; i++)     n[i] = 0;
    for(int i=0; i<64; i++)     m[i] = 0;

    n = convert(x, b, n);
    m = convert(y, b, m);
    
    int *_add = malloc(sizeof(int)*(64));
    _add = add(n, m, b, _add);
    free(_add);

    int *_mult = malloc(sizeof(int)*(64));
    _mult = mult(n, m, b, _mult);
    free(_mult);

    free(n);
    free(m);
    return 0;
}

问题原因与修复方案

崩溃的核心原因是mult函数中存在数组越界访问,破坏了malloc分配内存块的元数据,导致free时触发错误。

具体越界点分析

在mult函数的内层循环中:
当ind_m递减到1时,ind_arr初始值为63,随后内层ind_n从64循环到0,每次循环ind_arr减1。当循环结束时,ind_arr会变成63 - 64 = -1,此时执行arr[ind_arr] += carry,也就是访问arr[-1]——这属于非法的越界访问,会覆盖malloc内存块头部的元数据(比如内存大小标记),导致后续free(_mult)时系统无法识别合法的内存块,直接崩溃。

而add函数的循环始终在arr[0]到arr[63]的合法范围内访问,没有越界,所以free(_add)正常。

修复方法

修改mult函数中处理carry的逻辑,确保数组访问不越界:

// 替换原有的arr[ind_arr] += carry;
if (ind_arr >= 0) {
    arr[ind_arr] += carry;
}

或者重新梳理乘法的索引计算逻辑,从根源上避免ind_arr变为负数。

额外建议

  • 用calloc代替malloc加循环初始化,calloc会自动将内存初始化为0,代码更简洁:int *n = calloc(64, sizeof(int));
  • 调试数组越界问题时,可用gcc的地址 sanitizer(编译时加-fsanitize=address参数),能快速定位越界位置。

内容的提问来源于stack exchange,提问作者jamie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:47:45