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

C语言结构体int64_t值溢出:单项多项式构造异常排查

问题根源:野指针引发的未定义行为

你遇到的差异核心在于**polyFromRatio返回了指向局部变量的野指针**,而polyFromRatioArray使用的是指向有效内存的指针,这直接导致了两者运行结果的天差地别。

具体拆解差异原因:

  • 调用polyFromRatio(ra)时,ra是值传递给函数形参c——函数内部会创建一个ratio_t类型的局部变量c,把ra的值完整复制进去。这个c只存活在polyFromRatio的栈帧里,函数执行完毕后,栈帧被销毁,c占用的内存会被标记为可复用。
  • 函数返回&c,也就是这个已失效局部变量的地址。当后续调用polyPrint(p2)访问p2->coeffs[0]时,实际上是在访问已经被释放的栈内存,里面的数据是随机的垃圾值——这就是你看到异常分母140218959144480的原因,它根本不是原来的5,只是内存残留的随机数据。

而polyFromRatioArray(&ra, 0)能正常工作,是因为&ra指向的是main函数中的局部变量ra,这个变量在main执行全程都处于有效状态,所以p1->coeffs指向的是合法内存,数据自然正确。

两种修复方案:

方案1:为系数分配堆内存

在polyFromRatio中为ratio_t分配堆内存,复制参数值后再传入polyFromRatioArray:

poly_t polyFromRatio(ratio_t c){
    // 分配堆内存存储系数
    ratio_t *coeff = malloc(sizeof(ratio_t));
    if (coeff == NULL) {
        fprintf(stderr, "内存分配失败\n");
        exit(1);
    }
    *coeff = c; // 把参数值复制到堆内存
    return polyFromRatioArray(coeff, 0);
}

⚠️ 注意:使用该方案后,释放多项式时需要先释放coeffs的内存,再释放多项式结构体,避免内存泄漏:

// 正确释放p2的方式
free(p2->coeffs);
free(p2);

方案2:改为传递指针

把polyFromRatio的参数改为指针类型,直接复用polyFromRatioArray的逻辑:

poly_t polyFromRatio(ratio_t *c){
    return polyFromRatioArray(c, 0);
}

然后在main中调用时传入指针:

poly_t p2 = polyFromRatio(&ra);

这种方式无需额外分配内存,逻辑和p1完全一致,更简洁,但要确保传入的指针指向的变量在多项式使用期间一直有效。

额外提示:

野指针访问属于C语言中的未定义行为,它的表现完全不可控——这次只是出现奇怪的分母,下次可能直接导致程序崩溃,或者引发更隐蔽的逻辑错误。在C中一定要避免返回指向局部变量的指针。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:29:46