我的程序在Windows上看起来不错,而在Ubuntu上则崩溃了

时间:2019-06-20 14:06:02

标签: qt qt5

我正在用QT在Windows上编写一个飞机游戏,这看起来不错,而在Ubuntu上它已崩溃。它有一个QLinkedList<Bullet *> Bullet_list。在Bullet_list.removeOne(*ite)之后崩溃了

我尝试判断每个Null指针,在delete *ite之后添加removeOne(),但这是行不通的。

Plane_Player *Plane_p;

connect(timer,SIGNAL(timeout()),this,SLOT(Refresh()));
void GameWindow::Refresh(){
QLinkedList<Bullet*>::iterator ite;
       for(ite = Plane_p->Bullet_list.begin();ite != Plane_p->Bullet_list.end();++ite)
       {
           (*ite)->Go();//move the bullets on the screen
           if((*ite)->isOutOfBound())
               Plane_p->Bullet_list.removeOne(*ite);//crashed after this.
       }
}

class Plane_Player
{
public:
    QLinkedList<Bullet *> Bullet_list;
}

在函数Refresh()中,还有另一个removeOne(),之后全部崩溃了。

我希望它不会在Ubuntu上崩溃。 整个项目:https://github.com/Vinolzy/QT

2 个答案:

答案 0 :(得分:2)

Qt documentation指出:

  

如果要在中间插入,修改或删除项目   列表中,您必须使用迭代器。

到目前为止,一切都很好。但我认为问题在于,您从链接列表中删除了一个元素后就重用了迭代器。要修复它,您需要在删除后更新迭代器。例如,您可以像这样重写循环:

QLinkedList<Bullet*>::iterator ite = Plane_p->Bullet_list.begin();
while (ite != Plane_p->Bullet_list.end())
{
  (*ite)->Go();
  if ((*ite)->isOutOfBound())
  {
    ite = Plane_p->Bullet_list.erase(ite);
  }
  else
  {
    ++ite;
  }
}

最后,它在不同平台上的工作方式有所不同,因为您的代码导致未定义的行为。

答案 1 :(得分:1)

我认为Vahancho的答案可以解决这个问题,但是如果没有解决,我认为问题可能出在您循环遍历Plane_p时! 解决此问题的方法是在循环时以及完成循环时将plane_p复制并从其中删除,只需将复制对象的值放入plane_p中即可! 代码如下:

  QLinkedList<Bullet*>::iterator ite;
  Plane_Player *copy = *plane_p;
  for(ite = Plane_p->Bullet_list.begin();ite != Plane_p->Bullet_list.end();++ite)
       {
           (*ite)->Go();//move the bullets on the screen
           if((*ite)->isOutOfBound())
               copy->Bullet_list.removeOne(*ite);//crashed after this.
       }
  plane_p = *copy;