为什么我在这里得到一个向量下标超出范围错误?

时间:2013-06-03 21:23:07

标签: c++ vector

我正在创建一些rpg战斗,程序从.txt文件中读取输入。我创建了代码,但是当我想开始战斗时,它给了我一个超出范围的错误向量下标。任何人都可以帮我解决这个问题吗?非常感谢:)这里是代码。我包含了所有内容,所以你可以得到一个完整的上下文,但我认为主要的问题是在主cpp的while循环中,如果你想跳到那里。

因此我们在同一轨道上,lamanite(生命点和再生点)的txt文件的内容是

8 2

7 3

6 1

对于nephite它的

10 3

12 4

11 5

这是我的warrior.h文件

#pragma once
#include <string>

using namespace std;

class warrior
{
public:

    warrior ();
    warrior (int h, int r);
    int getDamage() const;
    void takeDamage(int damage);
    int getCurrentHP() const;
    void regenerate();
    string tostring(int h, int r);

private:
    int HitPoints;
    int RegPoints;
    int damage;


};

这是我的战士cpp

#include "warrior.h"
#include <string>
#include <iostream>

warrior::warrior(int h, int r)
{
    HitPoints = h;
    RegPoints = r;
}

int warrior::getDamage() const
{
    int damage = rand () % HitPoints;
    return damage;
}

void warrior::takeDamage(int damage)
{
    HitPoints = HitPoints - damage;
}

int warrior::getCurrentHP() const
{
    return HitPoints;
}

void warrior::regenerate() 
{
    HitPoints = HitPoints + rand () % (RegPoints);
}

string warrior::tostring(int h, int r)
{
    return 0;
}

我的主文件

#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <ctime>

#include "warrior.h"

using namespace std;

void main ()
{
    srand(time(0));
    ifstream input1;
    cout << "input file name nephite: ";
    string filename;
    cin >> filename;

    input1.open(filename);

    int HP1, RP1;
    vector <warrior*> nephites;

    while (input1 >> HP1 >> RP1)
    {
        nephites.push_back(new warrior(HP1, RP1));
    }

    cout << nephites.size() << endl;

    ifstream input2;
    cout << "input file name lamanite : ";
    string filename2;
    cin >> filename2;

    input2.open(filename2);
    int HP2, RP2;
    vector <warrior*> lamanites;

    while (input2 >> HP2 >> RP2)
    {
        lamanites.push_back(new warrior(HP2, RP2));
    }
    cout << lamanites.size() << endl;

    cout << endl << "Battle" << endl;

    warrior nephitesw  = warrior (HP1,RP1);
    warrior lamanitesw = warrior (HP2,RP2);

    while ((nephites.size() > 0) && (lamanites.size() > 0))
    {

        int rN = rand () % nephites.size();
        int rL = rand () % lamanites.size();
        cout << rN << "xx" << rL << endl; // so that i know what rN and rL is

        while((nephites[rN]->getCurrentHP() > 0) && (lamanites[rL]->getCurrentHP() > 0)) // the program can't execute this part of the code
        {
            nephites[rN]->takeDamage(lamanites[rL]->getDamage());
            lamanites[rL]->takeDamage(nephites[rN]->getDamage());

            if(lamanites[rL]->getCurrentHP() > 0)
            {
                lamanites[rL]->regenerate();
            }
            else
            {
                lamanites.erase(lamanites.begin() + (rL));
            } 

            if(nephites[rN]->getCurrentHP() > 0) 
            {
                nephites[rN]->regenerate();
            } 
            else
            {
                nephites.erase(nephites.begin() + (rN));
            }
        }

        cout << "NEP HP: " << nephites[rN]->getCurrentHP() << " " << "LAM HP: " << lamanites[rL]->getCurrentHP() << endl;
    }

    system ("Pause");
}

2 个答案:

答案 0 :(得分:3)

您有一个while循环,用于测试nephites[rN]lamanites[rL]的某些属性:

while((nephites[rN]->getCurrentHP() > 0) && (lamanites[rL]->getCurrentHP() > 0)
{
    // ...
}

但是在那个循环中你可能会删除这些元素:

{lamanites.erase(lamanites.begin() + (rL));} 

// ...

{nephites.erase(nephites.begin() + (rN));}  

至少,在其中一次擦除操作之后,你将在下一次循环迭代中测试一个不同的nephite或lamanite对象(这可能是也可能不是你想要的),但如果你已经删除了最后一次容器中的元素,您遇到索引现在超出范围的问题。

答案 1 :(得分:2)

您正在循环,直到nephites[rN]->getCurrentHP() <= 0lamanites[rL]->getCurrentHP() <= 0。但是,从0中删除最先降为vector的人:

// ...
{lamanites.erase(lamanites.begin() + (rL));} 

// ...            
{nephites.erase(nephites.begin() + (rN));}

如果rN == nephites.size()rN == lamanites.size()(当大小为1时肯定会发生,并且可能会在之前发生),这将导致您从vector开始索引当你测试循环时。

要快速解决问题,请移除将warriorvector移出循环的代码:

while((nephites[rN]->getCurrentHP() > 0) && (lamanites[rL]->getCurrentHP() > 0))
{
    nephites[rN]->takeDamage(lamanites[rL]->getDamage());
    lamanites[rL]->takeDamage(nephites[rN]->getDamage());

    if(lamanites[rL]->getCurrentHP() > 0)
    {
        lamanites[rL]->regenerate();
    }

    if(nephites[rN]->getCurrentHP() > 0) 
    {
        nephites[rN]->regenerate();
    } 
}

cout << "NEP HP: " << nephites[rN]->getCurrentHP() << " " << "LAM HP: " << lamanites[rL]->getCurrentHP() << endl;

// *****
// Move the erasures out of the loop
// *****

if(lamanites[rL]->getCurrentHP() <= 0)
{
    lamanites.erase(lamanites.begin() + (rL));
} 

if(nephites[rN]->getCurrentHP() <= 0)
{
    nephites.erase(nephites.begin() + (rN));
}