我在类中有一个方法,它获取指向另一个对象(另一个类)的指针,并将一个对象(另一个不同的类)添加到一个向量中,该向量是第一个对象的成员变量(作为参数传递)。这是代码:
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);
}
有没有办法防止这种情况发生?
答案 0 :(得分:2)
您正在将本地对象的地址传递给向量,一旦构造函数返回,则本地对象不存在,然后您的向量具有指向无效内存的指针。
你必须使对象持续存在,可能的方法是:
只需按值或按对象
使用动态分配的对象,而不是原始指针使用像shared_ptr
这样的智能指针作为向量元素类型。
答案 1 :(得分:1)
是的,您可以使用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 ++更原始指针。