1

我有一个小错误让我大吃一惊。也许这很简单,但我完全迷失了。

我有一个基本的 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!!

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

4

2 回答 2

4

如果以这种方式编写,则在返回过程中复制本地数据 (forReturn)。因此,以正确的方式实现 Data-class 的复制结构至关重要(以正确的方式复制所有成员)

于 2013-05-19T09:50:36.123 回答
2

除非我看到您拥有的真实代码,否则我无法确定,但我敢打赌,您的程序具有未定义的行为,因为您正在取消引用一个悬空指针。我相信在您的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 指针被复制,这意味着我返回的是一个类型的对象,Datavector指针指向一个已经超出范围的对象。

这是一颗定时炸弹。一旦该指针被取消引用,“ Boom ”。请注意,“繁荣”实际上可以是一个非常安静的爆炸 - 未定义的行为意味着任何事情都可能发生,包括什么也没有。

于 2013-05-19T10:11:27.907 回答