尝试访问向量中对象的指针时出现无效的访问错误

时间:2012-03-21 19:39:50

标签: c++

我在类中有一个方法,它获取指向另一个对象(另一个类)的指针,并将一个对象(另一个不同的类)添加到一个向量中,该向量是第一个对象的成员变量(作为参数传递)。这是代码:

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);
}

有没有办法防止这种情况发生?

2 个答案:

答案 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 ++更原始指针。