2012-07-14 97 views
0

从我读过的这个错误通常发生在迭代器出界时,但是我在空载体上遇到了这个问题。C++向量下标超出范围

这是保存矢量Player类:

Player.h:

#pragma once 
#include "Item.h" 
#include "Room.h" 
#include <vector> 
#include <memory> 
#include <string> 

using namespace std; 

class Player 
{ 
private: 
    int health; 
    string name; 
    shared_ptr<Room> currentRoom; 
    vector<shared_ptr<Item> > inventory; 

public: 
    Player(void); 
    Player(string); 
    ~Player(void); 
    void changeHealth(int); 
    void setRoom(shared_ptr<Room>); 
    shared_ptr<Room> getRoom(); 
    unsigned int getInventorySize(); 
}; 

Player.cpp:

#include "Player.h" 
#include <iostream> 
#include <memory> 
#include <string> 

Player::Player(void) 
{ 
    health = 20; 
} 

Player::Player(string newName) 
{ 
    name = newName; 
} 

Player::~Player(void) 
{ 
} 

void Player::changeHealth(int amount){ 
    health += amount; 
} 

void Player::setRoom(shared_ptr<Room> newRoom){ 
    currentRoom = newRoom; 
} 

shared_ptr<Room> Player::getRoom(){ 
    return currentRoom; 
} 

unsigned int Player::getInventorySize(){ 
    return inventory.size(); 
} 

我在球员注释掉所有其他方法影响库存。主要的是,我制作了一个播放器对象,但我没有做任何库存的事情,所以它应该是完全空的,并且getInventorySize应该返回0,对吧?但是当我这样做时:

cout<<player->getInventorySize(); 

该程序崩溃与向量下标超出范围错误。这是怎么回事? = \

全主:

#include "World.h" 
#include "Player.h" 
#include "Room.h" 
#include "Item.h" 
#include "Option.h" 
#include "RoomOption.h" 

#include <iostream> 
#include <memory> 
#include <string> 
#include <stdlib.h> 

typedef shared_ptr<Option> optionPtr; 
typedef shared_ptr<Item> itemPtr; 
typedef shared_ptr<Room> roomPtr; 

const int healthPackID =0; 
World world; 

void createWorld(void); 

void main(){ 

    createWorld(); 
    shared_ptr<Player> player = world.getPlayer(); 

    int selection = 0, inventoryOption = 0, exitOption = 0; 

    do{ 
     inventoryOption = player->getRoom()->getNumOptions() + 1; 
     exitOption = inventoryOption + 1; 

     cout<<player->getRoom()->getDescription()<<endl; 
     player->getRoom()->printOptions(); 
     cout<< inventoryOption <<". View Inventory"<<endl; 
     cout<< exitOption <<". Quit game"<<endl<<endl; 

     cin>>selection; 

     string optionType = typeid(*(player->getRoom()->getOption(selection- 1).get())).name(); 

     if(selection == inventoryOption){ 
      cout<<player->getInventorySize(); 
     } 
     else if(optionType.compare("class RoomOption") == 0){ 
      player->setRoom(player->getRoom()->getOption(selection- 1)->getRoom()); 
      cout<< "RoomOption!"<<endl; 
     } 
     else{ 
      cout<< "Not RoomOption =("<<endl; 
     } 

     system("CLS"); 

    }while(selection != exitOption); 

} 

void createWorld(){ 


    shared_ptr<Player> player(new Player("Ted")); 
    world.setPlayer(player); 

    roomPtr outside(new Room(0, "You're outside", "")); 
    roomPtr hallway(new Room(1, "It's a hallway", "")); 
    roomPtr kitchen(new Room(2, "It's the kitchen", "")); 
    roomPtr livingRoom(new Room(3, "You're in the living room", "")); 
    roomPtr upstairs(new Room(4, "You're on the upstairs landing but all the doors are  barred shut", "")); 


    outside->addOption(optionPtr(new RoomOption(0, "Go inside", hallway))); 

    hallway->addOption(optionPtr(new RoomOption(0, "Go straight ahead into the  kitchen", kitchen))); 
    hallway->addOption(optionPtr(new RoomOption(1, "Go right into the living  room", livingRoom))); 
    hallway->addOption(optionPtr(new RoomOption(2, "Go upstairs", upstairs))); 
    hallway->addOption(optionPtr(new RoomOption(3, "Go back outside", outside))); 

    hallway->addItem(itemPtr(new Item(healthPackID, "Health Pack", "A pack full of  first aid items like bandages and surgical spirits. Use it to increase your health", 3))); 

    kitchen->addOption(optionPtr(new RoomOption(0, "Go right into the living  room", livingRoom))); 
    kitchen->addOption(optionPtr(new RoomOption(1, "Go back into the hallway",  hallway))); 

    kitchen->addItem(itemPtr(new Item(1, "Cake", "A piece of tasty cake", 1))); 
    kitchen->addItem(itemPtr(new Item(2, "Beer", "A cold bottle of generic brand  beer", 1))); 

    livingRoom->addOption(optionPtr(new RoomOption(0, "Go left into the kitchen",  kitchen))); 
    livingRoom->addOption(optionPtr(new RoomOption(1, "Go back into the  hallway",hallway))); 

    upstairs->addOption(optionPtr(new RoomOption(0, "Go back downstairs", hallway))); 

    world.addRoom(outside); 
    world.addRoom(kitchen); 
    world.addRoom(livingRoom); 
    world.addRoom(hallway); 
    world.addRoom(upstairs); 

    player->setRoom(outside); 


} 
+0

需要解决此问题的所有代码。 – ForEveR 2012-07-14 14:03:54

+2

这段代码看起来很好。问题在于你*没有显示的代码。请构建一个[最小测试用例](http://sscce.org)。 – 2012-07-14 14:04:42

+0

getOption的实现如何? – 2012-07-14 14:14:36

回答

2
getOption(selection - 1) 

既然你增加两个额外的选项,那两个选项未包含在房间的选项载体内,从而导致索引出界失误。在致电getOption之前,您应该检查选择是否有效。

您应该首先检查selection == inventoryOption,如果不是(也不是退出选项),​​则计算optionType。更好的是,在计算optionType之前,请确保selection是有效的号码,否则如果用户输入无效号码,则会出现同样的问题。

+0

就是这样。哎呀!谢谢=) – 2012-07-14 14:27:54