[英]Pointer inside struct appears to change when struct is passed by value to function
问题涉及结构变量的 cmps 元素。
typedef struct Variable {
struct Variable *cmps[2];
double (*d_op)(void **a, struct Variable b);
double val;
} Variable;
Variable new_var(double a)
{
Variable v;
v.cmps[0] = NULL;
v.cmps[1] = NULL;
v.d_op = NULL;
v.val = a;
return v;
}
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;
}
int var_same(Variable a, Variable b)
{
if ((a.cmps[0] == b.cmps[0]) && (a.cmps[1] == b.cmps[1]))
{
return 1;
}
return 0;
}
double derivative(Variable a, Variable b)
{
printf("(a.cmps)[0]->val: %lf; (a.cmps)[1]->val: %lf\n", (a.cmps)[0]->val, (a.cmps)[1]->val);
if (var_same(a, b))
{
return 1.0;
}
if (a.cmps[0] == NULL)
{
return 0.0;
}
return a.d_op(a.cmps, b);
}
int main(int argc, char** argv)
{
Variable x = new_var(2.0);
Variable y = new_var(5.0);
Variable z = vs_mult(x, y);
eval(&z);
printf("(z.cmps)[0]->val: %lf; (z.cmps)[1]->val: %lf\n", (z.cmps)[0]->val, (z.cmps)[1]->val);
printf("%lf\n", derivative(z, x));
}
当上面的程序被执行时,立即输出是这样的:
(z.cmps)[0]->val: 2.000000; (z.cmps)[1]->val: 5.000000
(a.cmps)[0]->val: 2.000000; (a.cmps)[1]->val: 10.000000
为什么(a.cmps)[1]->val
不等于(z.cmps)[1]->val
?
Stackoverflow 想要更多细节,但我想我已经完整地概述了这个问题。 当然,我遗漏了几个函数定义,但它们应该无关紧要。
我不知道eval
在做什么,但你的代码中有一些非常危险的东西:
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;
}
请注意,函数参数a
和b
是局部变量,它们的生命周期在vs_mult
返回时vs_mult
。 因此cmps
中的值是悬空指针。 使用它们的值( eval
可能会这样做)会调用未定义的行为。
为了解决这个问题, vs_mult
应该使用指向变量的指针。
Variable vs_mult(Variable *a, Variable *b)
{
Variable v = new_var(0.0);
v.cmps[0] = a;
v.cmps[1] = b;
...
}
但是,现在调用者负责确保两个变量的生命周期都封装了vs_mult
返回的值的生命vs_mult
。
或者,您可以尝试引用计数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.