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
相关产品推荐
相关产品推荐

