【问题标题】:How to fix 'Expression: vector subscript out of range' error [closed]如何修复“表达式:向量下标超出范围”错误 [关闭]
【发布时间】:2019-08-08 16:08:24
【问题描述】:

我正在通过SFML制作一个简单的游戏,遇到以下错误:

调试断言失败! 表达式:向量下标超出范围

此错误仅在“火箭”与第一个“敌人”接触时出现,同时屏幕上有 3 个敌人。

    for (int i = 0; i < rockets.size(); i++) //This is where the error points to
    {
        for (int j = 0; j < enemies.size(); j++)
        {
            Rocket *rocket = rockets[i];
            Enemy *enemy = enemies[j];

            if (checkCollision(rocket->getSprite(), enemy->getSprite()))
            {
                //hitSound.play();
                score++;
                std::string finalScore = "Score: " + std::to_string(score);
                scoreText.setString(finalScore);
                sf::FloatRect scoreBounds = scoreText.getGlobalBounds();
                scoreText.setOrigin(scoreBounds.width / 2, scoreBounds.height / 2);
                scoreText.setPosition(viewSize.x * 0.5f, viewSize.y * 0.10f);



                rockets.erase(rockets.begin() + i);
                enemies.erase(enemies.begin() + j);

                delete(rocket);
                delete(enemy);
                if (score % 5 == 0) levelUp();
                printf("rocket intersects with enemy \n");
            }
        }
    }

我已将敌人和火箭对象存储在向量中:

    std::vector <Enemy*> enemies;
    std::vector <Rocket*> rockets;

如果有帮助,这是我的整个更新功能:

void update(float dt)
{
    hero.update(dt);

    currentTime += dt;
    if (currentTime >= prevTime + 1.125f)
    {
        spawnEnemy();
        prevTime = currentTime;
    }

    for (int i = 0; i < enemies.size(); i++)
    {
        Enemy *enemy = enemies[i];
        enemy->update(dt);

        if (enemy->getSprite().getPosition().x < 0)
        {
            enemies.erase(enemies.begin() + i);
            delete(enemy);
            gameOver = true;
            gameOverSound.play();
        }
    }

    for (int i = 0; i < rockets.size(); i++)
    {
        Rocket *rocket = rockets[i];

        rocket->update(dt);

        if (rocket->getSprite().getPosition().x > viewSize.x)
        {
            rockets.erase(rockets.begin() + i);
            delete(rocket);
        }
    }

    for (int i = 0; i < rockets.size(); i++)
    {
        for (int j = 0; j < enemies.size(); j++)
        {
            Rocket *rocket = rockets[i];
            Enemy *enemy = enemies[j];

            if (checkCollision(rocket->getSprite(), enemy->getSprite()))
            {
            //hitSound.play();
                score++;
                std::string finalScore = "Score: " + std::to_string(score);
                scoreText.setString(finalScore);
                sf::FloatRect scoreBounds = scoreText.getGlobalBounds();
                scoreText.setOrigin(scoreBounds.width / 2, scoreBounds.height / 2);
                scoreText.setPosition(viewSize.x * 0.5f, viewSize.y * 0.10f);



                rockets.erase(rockets.begin() + i);
                enemies.erase(enemies.begin() + j);

                delete(rocket);
                delete(enemy);
                if (score % 5 == 0) levelUp();
                printf("rocket intersects with enemy \n");
            }
        }
    }

    for (int i = 0; i < enemies.size(); i++)
    {
        Enemy *enemy = enemies[i];

        if (checkCollision(enemy->getSprite(), hero.getSprite()))
        {
            gameOver = true;
            gameOverSound.play();
        }
    }
}

【问题讨论】:

  • 你是通过调试器运行的吗?另外,不要在容器内使用指针,如果必须有持久化迭代器,请使用 shared_ptr
  • 这是一个调试器的明确工作。
  • 您可以修复错误,逐行调试代码并找到索引变量超出范围的位置。
  • 如果你有 1 个火箭和 3 个敌人,第一个敌人与火箭相撞后火箭矢量会发生什么变化?
  • 你不能在循环中从向量中删除元素。您应该将它们标记为计划删除并稍后删除它们的对象,例如使用 stl:std::remove_if

标签: c++ visual-studio sfml


【解决方案1】:

您无法在迭代向量时从向量中删除元素。您正在删除元素,但没有正确调整 i 和 j,因此您最终超出了索引范围。

【讨论】:

  • 但是我不明白为什么当屏幕上只有 2 个敌人时错误没有出现。为什么只有同时屏幕上有 3 个或更多敌人时才会出现这种情况?
  • 这是未定义的行为。删除对象不会擦除内存,它只是允许程序回收它。即使您删除数据,数据也可能有效。我注意到的另一件事是,当火箭相撞时,您将其删除,但您继续遍历其他敌人并检查火箭是否与他们相撞。它创建了一个场景,您可能会两次删除火箭。这绝对是无效的行为。
  • 请将此标记为已接受的答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-06
相关资源
最近更新 更多