返回的值与实际返回的值不相同

Value of return is not same as value actually returned?

本文关键字:返回      更新时间:2023-10-16

我有一个小bug,让我心烦意乱。也许这很简单,但我完全迷路了。

我有一个基本的POD struct:

    struct Data{
    bool isInvalid=false;
    vec3 *vector; //vec3 is another struct with x,y,z components
    Node*node;
    bool isFresh;
    unsigned int *form;
    };

我有一个函数:

  Data getData(){
    Data forReturn;
    //...populates the forReturn struct
    cout<<forReturn.vector->x; //logs correctly a value 
    return forReturn;
   }

cout日志正确地显示我的返回Data已被填充。但是当我从另一个函数中调用这个函数时,出现了一个不同的故事:

  Data newData=getData(); //logs as above
  cout<<newData.vector->x; //is empty!!

这是怎么回事?我的日志输出显示这两行并排出现,因为它们紧接在一起,但是发生了什么?这不是多线程的,所以变量和指针不应该在这两行之间改变!

如果这样写,则在返回过程中复制本地数据(forReturn)。因此,以正确的方式实现data类的复制构造函数(以正确的方式复制所有成员)

至关重要。

除非我看到您的实际代码,否则我无法确定,但我打赌您的程序具有未定义行为,因为您正在解引用悬空指针。我相信在您的getData()函数中,您让forReturn.vector指向具有自动存储持续时间的本地对象,该对象在从getData()返回时被销毁,如下所示:

Data getData(){
    Data forReturn;
    vec3 myVector;
    // ...
    forReturn.vector = &myVector;
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    // ...
    cout<<forReturn.vector->x; // logs correctly a value 
    return forReturn;
}

在上面的例子中,我按值返回Data对象forReturn,这意味着将调用隐式声明的移动构造函数(在c++ 11中)或复制构造函数(在c++ 03中)。

由于这些隐式生成的特殊成员函数执行按成员移动或复制数据结构的成员,因此复制了vector 指针,这意味着我返回的是Data类型的对象,其vector指针指向已经超出作用域的对象。

这是一个定时炸弹。一旦该指针被解引用,"Boom"。注意,"Boom"实际上可以是一个非常无声的爆炸——未定义行为意味着任何都可能发生,包括什么都不发生。