問題涉及結構變數的 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 想要更多細節,但我想我已經完整地概述了這個問題。當然,我遺漏了幾個函式定義,但它們應該無關緊要。
uj5u.com熱心網友回復:
我不知道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回傳時結束。因此,值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。
或者,您可以嘗試參考計數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/335263.html
標籤:C
上一篇:將整數中的每個數字存盤在陣列中
