我在一个类中有一个方法,它是指向另一个对象(不同类的)的指针,并将一个对象添加到向量中,该向量是第一个对象(作为参数传递的对象)的成员变量。这是代码:
ObstacleManager::ObstacleManager(Application *lApp)
{
app=lApp;
GLfloat obstacleVerts[12]={
-0.1f,-0.2f,0.0f,
0.1f,-0.2f,0.0f,
-0.1f,0.2f,0.0f,
0.1f,0.2f,0.0f
};
StandardObstacle obstacle(obstacleVerts,-0.7f,0.0f,4);
obstacle.manager=this;
lApp->characters.push_back(&obstacle);
}
我认为问题是,障碍物在不该释放的时候会被释放,因为如果我更改代码并用"new"创建障碍物(如果你用new创建了一个对象,你必须手动删除它,不是吗?)这是有效的。像这样:
ObstacleManager::ObstacleManager(Application *lApp)
{
app=lApp;
GLfloat obstacleVerts[12]={
-0.1f,-0.2f,0.0f,
0.1f,-0.2f,0.0f,
-0.1f,0.2f,0.0f,
0.1f,0.2f,0.0f
};
StandardObstacle *obstacle=new StandardObstacle(obstacleVerts,-0.7f,0.0f,4);
obstacle->manager=this;
lApp->characters.push_back(obstacle);
}
有没有办法防止这种情况发生?
您正在将本地对象的地址传递给向量,一旦构造函数返回,本地对象就不存在,并且您的向量有一个指向无效内存的指针。
您必须使对象持久化,可能的方法有:
只需按值或
推送对象使用动态分配的对象,但不要使用原始指针,而是使用像shared_ptr
这样的智能指针作为矢量元素类型。
是的,您可以使用new
创建对象,也可以使用智能指针。
你的直觉是正确的:
ObstacleManager::ObstacleManager(Application *lApp)
{
//...
StandardObstacle obstacle(obstacleVerts,-0.7f,0.0f,4);
obstacle.manager=this;
lApp->characters.push_back(&obstacle);
} //obstacle is destroyed here
对象obstacle
是在自动存储器中创建的。它的生存期受到其封闭范围的限制,封闭范围是构造函数中的右括号。
所以你取一个对象的地址,把它推到你的向量中,然后这个对象就被破坏了。这意味着,在向量内部,现在有一个悬挂的指针。
这肯定会导致未定义的行为。
您可以使用new
,并确保清理内存。或者你可以使用智能指针——它比原始指针更像C++。