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



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

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++。

最新更新