c++ - 在对象内部和外部调用函数的不同行为

标签 c++ c++11

我的 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/

相关文章:

java - 通过 JNI 将我的 Java API 扩展到 C++ : How to wrap a method returning a String?

c# - 将 C++ map 数据传递给 C#

c++ - C++ 前缀递增运算符返回左值这一事实的实际应用

c++ - 如何通过可变构造函数调用复制构造函数?

c++ - 引用变量在内存中是如何表示的?

c++ - Foo f = Foo();//没有调用 'Foo::Foo(Foo)' 的匹配函数……嗯?

c++ - boost 宣传 - 需要帮助

c++ - 指向二维数组的指针

c++ - 是否可以从 std::bind 对象访问参数?

c++ - 对临时对象的 const 引用的列表初始化