【问题标题】:Segmentation fault during erasing from vector从向量中擦除期间的分段错误
【发布时间】:2017-12-14 18:49:00
【问题描述】:

我正在开发小行星游戏克隆,但在从小行星矢量中擦除元素时遇到问题。所以一般来说,当我撞击小行星时,它应该分成三部分。因此,我创建了 3 颗新的小行星并擦除了旧的一颗,然后它就崩溃了。

void Level::missleAsteroidCollision(){
    std::cout<<this->asteroidVector.size()<<std::endl;
    for(auto ptr = this->missleVector.begin();ptr!=this->missleVector.end();++ptr){
            sf::FloatRect missleBounds = (*ptr)->shape.getGlobalBounds();
            for(auto ptrTwo = this->asteroidVector.begin(); ptrTwo!= this->asteroidVector.end();++ptrTwo){
                if(missleBounds.intersects((*ptrTwo)->shape.getBounds()) && (*ptrTwo)->isFinalForm == false){
                    for(int i = 0; i < 3; ++i){
                        this->createAsteroid((*ptrTwo)->origin,true);
                    }
                    delete *ptrTwo;
                    this->asteroidVector.erase(ptrTwo);
                }
                else if(missleBounds.intersects((*ptrTwo)->shape.getBounds()) && (*ptrTwo)->isFinalForm == true){
                    delete *ptrTwo;
                    this->asteroidVector.erase(ptrTwo);
                }
            }
    }
}

【问题讨论】:

标签: c++ vector erase fault


【解决方案1】:

首先,当您使用 .erease 函数时,迭代器已更改,因此您需要更新它,在您的情况下,ptr = this-&gt;asteroidVector.erase(ptrTwo); 迭代器现在将指向删除后的下一个元素,因此请记住这一点(如果不使用 .erase 函数,要么将指针减一,要么只增加 ptr (ptr++)。

其次,我相信this-&gt;createAsteroid((*ptrTwo)-&gt;origin,true); 会创建新项目,这也会使迭代器无效,因此一种解决方法可能是在检查并删除旧的小行星后创建新的小行星。也许将新的小行星存储在 for 循环之前创建的向量中,在那里添加新的陨石,然后在 for 循环之后将向量添加到当前的小行星向量中。

【讨论】:

  • 另一种选择是向后迭代。只有被擦除元素处或之后的迭代器才会失效。
【解决方案2】:

将一个项目插入到向量中(无论是否在向量的末尾)都会使该向量的所有迭代器无效。我怀疑你的 createAsteroid 会这样做。

【讨论】:

  • 是的,createAsteroid() 将新对象推送到 asteroidVector。有什么建议可以解决这个问题吗?
猜你喜欢
  • 1970-01-01
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 2018-08-01
  • 2017-04-17
  • 2023-03-17
  • 2019-10-09
  • 1970-01-01
相关资源
最近更新 更多