我的 C++ 代码发生了一些非常奇怪的行为。我的 MultiplyOperation 类中有一个函数 backward(),我从另一个对象 FloatTensor 类调用它,该类具有此 MultiplyOperation 类的实例。
如果我调用 three.backOperation->backward(1);
和 three.backOperation->backward(1);
,输出的结果是不同的,而它应该是一样的。请帮忙。
这是我的代码:
#include<iostream>
using namespace std;
class FloatTensor;
class MultiplyOperation{
public:
FloatTensor *t1, *t2;
float grad = 10;
MultiplyOperation(FloatTensor* t1, FloatTensor* t2);
FloatTensor compute();
void backward(float gradient);
};
class FloatTensor {
public:
float val;
float grad;
MultiplyOperation* backOperation = NULL, *frontOperation = NULL;
FloatTensor() {
// default
}
FloatTensor(float value) {
this->val = value;
this->backOperation = NULL;
}
FloatTensor(float value, MultiplyOperation* backOp) {
this->val = value;
this->backOperation = backOp;
}
void backward(float gradient) {
this->backOperation->backward(gradient);
}
FloatTensor operator * (FloatTensor two) {
MultiplyOperation ope(this,&two);
this->frontOperation = &ope;
return this->frontOperation->compute();
}
};
MultiplyOperation::MultiplyOperation(FloatTensor* te1, FloatTensor* te2) {
this->t1 = te1;
this->t2 = te2;
}
FloatTensor MultiplyOperation::compute() {
return FloatTensor(this->t1->val*this->t2->val, this);
}
void MultiplyOperation::backward(float gradient) {
cout<<this->t2->val<<endl;
}
int main() {
FloatTensor one(2);
FloatTensor two(4);
FloatTensor three = one*two;
three.backOperation->backward(1); // should be same as output of next line and is 4. (which is correct)
three.backward(1); // should be same as output of above line but is garbage value -4.12131
}
最佳答案
由于以下函数,您的程序具有未定义的行为:
FloatTensor operator * (FloatTensor two) {
MultiplyOperation ope(this,&two);
this->frontOperation = &ope;
return this->frontOperation->compute();
}
您正在存储一个指向对象的指针,ope
,一旦函数返回,它就不再有效。
在创建ope
时使用two
也存在同样的问题。
您可以更改函数以存储指向动态分配对象的指针来解决该问题。
FloatTensor operator * (FloatTensor two) {
this->frontOperation = new MultiplyOperation(this, new FloatTensor(two));
return this->frontOperation->compute();
}
或使用
FloatTensor operator * (FloatTensor& two) {
this->frontOperation = new MultiplyOperation(this, &two);
return this->frontOperation->compute();
}
请注意,最好使用智能指针而不是原始指针。否则,您的程序将继续面临遇到更多内存相关问题的风险。
关于c++ - 在对象内部和外部调用函数的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54498998/