我有个小虫子让我大吃一惊。也许这很简单,但我完全迷惑了。
我有一个基本的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!!这里发生什么事情?!我的日志输出显示这两行并排出现,因为它们紧跟在另一行之后,但是发生了什么呢?这不是多线程的,所以变量和指针不应该在这两行之间改变!
发布于 2013-05-19 18:11:28
除非我看到你的真实代码,否则我不能确定,但我敢打赌,你的程序有未定义的行为,因为你正在取消引用一个悬空指针。我相信在您的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“。请注意,“轰隆”实际上可以是一种非常无声的爆炸-未定义的行为意味着任何事情都可能发生,包括什么都不发生。
发布于 2013-05-19 17:50:36
如果以这种方式写入,则会在返回过程中复制本地数据(forReturn)。所以至关重要的是你的数据类的复制结构是以正确的方式实现的(以正确的方式复制所有成员)
https://stackoverflow.com/questions/16633336
复制相似问题