【问题标题】:Vector subscript out of range with nested for loops带有嵌套 for 循环的向量下标超出范围
【发布时间】:2018-05-02 04:56:30
【问题描述】:

下面是我用 SFML 用 c++ 编写的游戏中的一个 sn-p 代码。

    if (Keyboard::isKeyPressed(Keyboard::Space)) {
        if (fireClock.getElapsedTime().asMilliseconds() > 150) {
        Bullet vecBullet(Vector2f(player->getPosition()), player->angle);
        bulletVector.push_back(vecBullet);
        sleep(milliseconds(5));
        fireClock.restart();
    }
}

if (Keyboard::isKeyPressed(Keyboard::A)) {
    Enemy vecEnemy;
    enemyVector.push_back(vecEnemy);
}

for (int i = 0; i < bulletVector.size(); i++) {
    bulletVector[i].fire();
    bulletVector[i].draw();
}
for (int i = 0; i < enemyVector.size(); i++) {
    enemyVector[i].draw();
}

for (int i = 0; i < bulletVector.size(); i++) {
    if (bulletVector[i].getPosition().x > 2000 || bulletVector[i].getPosition().x < -100 ||
        bulletVector[i].getPosition().y > 1100 || bulletVector[i].getPosition().y < -100) {
        bulletVector.erase(bulletVector.begin() + i);
    }
}

for (int y = 0; y < bulletVector.size(); y++) {
    for (int x = 0; x < enemyVector.size(); x++) {
        if (enemyVector.size() > 0 && bulletVector.size() > 0) {
            if (enemyVector[x].checkColl(Bullet(bulletVector[y]))) {
                bulletVector.erase(bulletVector.begin() + y);
                enemyVector.erase(enemyVector.begin() + x);
            }
        }
    }
}

cout << enemyVector.size() << " " << bulletVector.size() << endl;

发生的情况是,一旦子弹被击中,它就会击中敌人,有时它会崩溃并抛出以下错误:

程序:C:\WINDOWS\SYSTEM32\MSVCP140D.dll 文件:c:\program 文件 (x86)\微软 visualstudio\2017\community\vc\tools\msvc\14.13.26128\include\vector 线路:1806

表达式:向量下标超出范围

您能给我的任何见解将不胜感激, 谢谢你。

【问题讨论】:

  • 如果bulletVector.erase(bulletVector.begin() + y) 删除最后一个元素,bulletVector[y] 在循环的下一次迭代中将访问越界索引。在任何情况下,即使索引 y 仍然有效,请注意您实际上跳过了已擦除元素之后的元素。
  • @IgorTandetnik 感谢您的快速回复

标签: c++ vector sfml


【解决方案1】:

正如@Igor Tandetnik 指出的那样,您可以是deleting an element from your array while iteratingbulletVector.erase(bulletVector.begin() + y);

关于thistopic,SO 上有plentyexamples,我可能不会更好地解释它。


我想在您的代码中指出一些额外的内容。在本节中:

for (int y = 0; y < bulletVector.size(); y++) {
    for (int x = 0; x < enemyVector.size(); x++) {
        if (enemyVector.size() > 0 && bulletVector.size() > 0) {
            if (enemyVector[x].checkColl(Bullet(bulletVector[y]))) {
                bulletVector.erase(bulletVector.begin() + y);
                enemyVector.erase(enemyVector.begin() + x);
            }
        }
    }
}

在哪里寻找碰撞,这句话是多余的:

if (enemyVector.size() &gt; 0 &amp;&amp; bulletVector.size() &gt; 0) {

如果两个向量中的任何一个为空,则至少有一个 for 循环不会迭代单个循环,因此您可以删除该检查并节省一些计算和代码行。

此时,您要确保两个向量内部至少有 1 个元素。

【讨论】:

    猜你喜欢
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多