Search code examples
c++vectorsfml

Vector subscript out of range with nested for loops


below is a snippet of code from a game I am writing in c++ with SFML.

    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;

What happens is that once the bullet is shot it hits the enemy and sometimes it crashes and throws the following error:

program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll File: c:\program files (x86)\microsoft visualstudio\2017\community\vc\tools\msvc\14.13.26128\include\vector Line: 1806

Expression: vector subscript out of range

Any insights you can give me would be greatly appreciated, Thank you.


Solution

  • As @Igor Tandetnik pointed out, you could be deleting an element from your array while iterating with bulletVector.erase(bulletVector.begin() + y);

    There are plenty of examples on SO about this topic, and I probably won't explain it better.


    I'd like to point something extra in your code. In this section:

    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);
                }
            }
        }
    }
    

    where you look for collisions, this sentence is redundant:

    if (enemyVector.size() > 0 && bulletVector.size() > 0) {

    If any of both vectors is empty, at least one of the for loops won't iterate a single loop, so you could remove that check and save some computation and lines of code.

    At that point, you ensure that both vectors have at least 1 element inside.