繁体   English   中英

当 struct 按值传递给函数时,struct 内部的指针似乎发生了变化

[英]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;
}

请注意,函数参数ab是局部变量,它们的生命周期在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM