C语言结构体按值传递时内部cmps指针指向值异常变化原因
问题原因分析
核心问题:代码中存在悬垂指针(野指针),非法访问了已被系统回收的栈内存。
具体原因说明
- C语言函数参数默认是值传递,你定义的
vs_mult(Variable a, Variable b)的两个参数a、b都是函数内部的栈上临时变量,生命周期仅在vs_mult函数执行期间有效。 - 你在
vs_mult中直接将v.cmps[0] = &a、v.cmps[1] = &b,相当于把cmps指针指向了栈上的临时变量地址。当vs_mult执行结束返回后,这部分栈内存会被系统回收,允许后续函数调用复用这块空间存储新数据,这两个地址就变成了无效的悬垂指针。
两次打印结果不一致的原因
- main函数中第一次打印
z.cmps时,刚执行完eval,回收的栈空间还没被新的操作覆写,所以还能读到临时变量原来的值5.0。 - 调用
derivative函数时,函数参数、内部变量会占用栈空间,刚好覆写了原来b临时变量对应的栈内存,所以从悬垂指针里读到的是被覆写后的10.0(这个值是不确定的,完全取决于后续栈空间的使用逻辑,只是当前运行环境下刚好被覆写为10)。
修复方案
如果要让cmps指向main函数里的x、y变量,需要把vs_mult的参数改成指针类型,避免值传递产生临时拷贝:
// 修改函数定义 Variable vs_mult(Variable *a, Variable *b) { Variable v = new_var(0.0); v.cmps[0] = a; v.cmps[1] = b; v.d_op = &d_mult; return v; } // 调用的时候传地址 Variable z = vs_mult(&x, &y);
内容的提问来源于stack exchange,提问作者user363406
相关产品推荐
相关产品推荐

