C ++ - 矢量迭代器+偏移超出范围

时间:2013-11-02 23:31:01

标签: c++ vector

我已经查看过10条关于同一条消息的答案,但还没有找到我的问题。

Level类中的level.h中的

std::vector<Bomb> m_bombs;

在level.cpp中:

添加炸弹:

Bomb bomb;
bomb.owner = player;
bomb.power = power;
bomb.x = pos.x;
bomb.y = pos.y;
bomb.timer = 3.0f;
m_bombs.push_back(bomb);

检查炸弹(每一帧):

void Level::updateBombs(float dt)
{
    for(int i = 0; i < m_bombs.size(); i++)
    {
        m_bombs[i].timer -= dt;
        if(m_bombs[i].timer <= 0)
            m_bombs.erase(m_bombs.begin() + i);
    }
}

我100%确定程序在调用擦除函数的行上崩溃。我能够从向量输出信息,这使得这种方式更加混乱。炸弹在矢量中是正确的。如果我执行m_bombs.remove_last(),它将删除向量中的最后一个元素。似乎只有擦除问题和begin()。

4 个答案:

答案 0 :(得分:1)

也许你可以尝试向后擦除矢量,例如如果要清除炸弹索引3和5,则删除索引为5然后为3的索引,因为如果从0顺序擦除到N-1,则在擦除索引3时,则索引5将成为索引4,这可能导致在到达循环的最后一步时超出界限。

试试这个:

int pivot = 0
void Level::updateBombs(float dt)
{
    for(int i = 0; i < m_bombs.size(); i++)
    {
        m_bombs[i].timer -= dt;
        if(m_bombs[i].timer <= 0)
        {
            m_bombs.erase(m_bombs.begin() + i - pivot);
            pivot++;
        }

    }
}

答案 1 :(得分:1)

您可以使用erase-remove-idiom修复代码。

m_bombs.erase(std::remove_if(m_bombs.begin(), m_bombs.end(), 
                             [](const Bomb& b){ return b.timer < 0.0f;}), 
                             m_bombs.end());

更好地将updateBombs函数拆分为两个函数:

updateBombs() does bomb timer update only
removeBombs() removes bombs which expired

答案 2 :(得分:0)

清除或创建向量时,我遇到了类似的问题。 出现问题的原因是在运行时使用了2个不同版本的dll。在调用Open CV函数时发生了清除和创建,这些函数似乎使用与我的visual studio不同的运行时库。 改变视觉工作室最终修复了问题(我在改变视觉工作室之前尝试了很多旧的OpenCV版本,但无济于事)。 VS 2008和VS不起作用,VS2010确实如此。

答案 3 :(得分:0)

我会将m_bombs.size()替换为您自己的int变量,并在移除炸弹后减少。我个人遇到.size()的问题。它应该返回向量中的元素数量,但我有一个空向量,.size()返回的数字大于零。也许尝试这会有助于缩小你的问题。