将第N个元素从元素K-1

时间:2019-05-17 16:39:22

标签: c++ vector memory-management null sigsegv

我最近开始学习OpenGL。我在Learnopengl.com教程的每个部分之后都有测试自己的技能的想法,并且
目前在https://learnopengl.com/Getting-started/Shaders章之后

所以我创建了一个简单的乒乓游戏,在调试时我注意到了奇怪的行为。
我创建的游戏会在一段时间后崩溃,但总是在其中一位玩家获得积分后崩溃。
重要的是要注意,每个游戏对象都有一个更新函数,我将每一帧称为
,并且将指向所有游戏对象的指针保存在STL向量中。

我分析了一些代码,发现它没什么不好,所以我启动了gdb并写了一些“ std :: cerr”信息。
这是我发现的:
1.更新其中一个对象(obj-> update())
时游戏崩溃 2.在将新点数授予玩家后,游戏总是崩溃,从而使游戏对象指针向量包含32个元素。如果我在游戏开始之前使用GAMEOBJECTS.relocate(33),则当崩溃时矢量包含33个元素。
3.从向量更新第五个游戏对象时,游戏崩溃。这里必须注意,ball对象是第四个,而Ball :: update()包含创建新GameObject(点)的代码。


从这些信息中,我推断出,当我创建一个新对象并将其指针推到一个矢量上时,该矢量必须自行重定位,因为它没有足够的容量。
反过来,这会导致一些我不理解的奇怪的内存混乱,因为我才刚刚开始学习c ++编程。
这也使得无法访问向量的第五个元素。
我正在努力寻找解决此问题的方法,但我最大的担心是了解为什么会这样。

代码太大,无法粘贴到这里,所以我将其放在github:
https://github.com/carul/opengl_pong

我仍将描述我认为最重要的内容:

for(auto && obj : GAMEOBJECTS){
  obj->update();
  obj->draw(VBO);
}

这就是我用来绘制和更新游戏对象的循环。
我认为这没什么特别的,除了它可以一个接一个地更新对象。

void Ball::update(){
   ///...
   if(boundingLeft < -0.96f){
    this->setPosition(0.0f, 0.0f);
    this->speedmodif = 0.8f;
    this->angle = 0;
    Point * point = new Point(GL_STATIC_DRAW);
    point->create(POINT_DATA);
    point->indice(POINT_INDICES);
    point->setPlayer(2);
    point->name = "POINT";
    point->setPosition(0.93f - 0.03f*scorep2, 0.9f);
    scorep2++;
    GAMEOBJECTS.push_back(point);
  }
  if(boundingRight > 0.96f){
    this->setPosition(0.0f, 0.0f);
    this->speedmodif = 0.8f;
    this->angle = M_PI;
    Point * point = new Point(GL_STATIC_DRAW);
    point->create(POINT_DATA);
    point->indice(POINT_INDICES);
    point->setPlayer(1);
    point->name = "POINT";
    point->setPosition(-0.95f + 0.03f*scorep1, 0.9f);
    scorep1++;
    GAMEOBJECTS.push_back(point);
  }
  ///...
}

这是球的更新功能的一部分。这段代码负责创建新点。 Ball是Object类的派生类。
GAMEOBJECTS的定义如下:
std::vector<Object * > GAMEOBJECTS;

很抱歉很长的帖子,我试图提供我所有的信息。
非常感谢您阅读本文的这一部分,并感谢您的帮助

这是崩溃时gdb和游戏的屏幕截图:
screenshot

1 个答案:

答案 0 :(得分:2)

在此循环中

for(auto && obj : GAMEOBJECTS) {
    obj->update();
    obj->draw(VBO);
}

obj是对向量元素的引用。在update()中,您push_back()进入GAMEOBJECTS。如果向量的容量不足以容纳新元素,则此操作会使obj引用无效。