Search code examples
c++pointersdynamic-memory-allocationbad-alloc

"bad_alloc" exception thrown during a method call


I've searched high and low for a solution to this problem and couldn't find one, so I've resorted to just asking. My program is a maze game containing a number of different rooms, each of which is linked to one or more adjacent rooms using pointers. The player navigates their way from room to room until they find the exit.

When the program gets to this line in my Turn() function, the call to getName() throws a "bad_alloc" exception:

cout << "You are currently in " << current->getName()
//that's not the entire line but it's the important bit

All getName() does is return the room's name as a string. current is a pointer of type Room*, that points to the room the user is currently in. I'm guessing that this pointer is where the problem lies, but it's clearly defined in main():

int main()
{
    //first I create a Maze object to hold important variables, and then the nineteen rooms
    Maze maze = Maze();
    Room room1 = Room("Room A");
    Room room2 = Room("Room B");
    Room room3 = Room("Room C");
    //and so on...
    Room empty = Room("");  //used as a placeholder for rooms with less than five adjacent rooms

    //set the rooms adjacent to each room
    room1.SetAdjacent(room2, room3, room4, empty, empty);
    room2.SetAdjacent(room1, room5, room6, empty, empty);
    room3.SetAdjacent(room1, room6, room7, room15, empty);
    //and so on...

    //this explicitly sets the "current" pointer to point to room1:
    maze.SetCurrent(&room1);

    cout << "Welcome to The Maze Game. Can you find your way out?" << endl;
    system("pause");

    do
    {
        maze.Turn();
        if (maze.GetWinStatus() == true)
        {
            cout << "You have reached the exit! Congratulations!" << endl;
        }
        system("pause");
    } while (maze.GetWinStatus() == false);  //if the player hasn't moved to the exit, then it loops round for another turn

    return 0;
}

So I can't figure out why on earth it's throwing this exception. If you want to look at any of the other code, please ask and I'll gladly post it here.

EDIT 2: Here's the entire Room class, as requested:

class Room
{
private:
    string roomName;
    Room* adjacentRooms[5];
public:
    Room(string name);
    string getName();
    void SetAdjacent(Room adj1, Room adj2, Room adj3, Room adj4, Room adj5);
    Room* GetAdjacent(int room);
};

Room::Room(string name)
{
    roomName = name;
}

string Room::getName()  //this is the bit that makes it crash
{
    return roomName;
}

void Room::SetAdjacent(Room adj1, Room adj2, Room adj3, Room adj4, Room adj5)
{   //sets which rooms are adjacent to the room this function is called from
    adjacentRooms[0] = &adj1;
    adjacentRooms[1] = &adj2;
    adjacentRooms[2] = &adj3;
    adjacentRooms[3] = &adj4;
    adjacentRooms[4] = &adj5;
}

Room* Room::GetAdjacent(int room)
{   //returns one of the five adjacent rooms. Numbers 1-5 are used as inputs for user convenience
    return adjacentRooms[room - 1];   //the number is lowered by 1 to get the right room in the array
}

Solution

  • Your problem is your SetAdjacent method:

    void SetAdjacent(Room adj1, Room adj2, Room adj3, Room adj4, Room adj5);
    

    should take in its parameters by reference:

    void SetAdjacent(Room& adj1, Room& adj2, Room& adj3, Room& adj4, Room& adj5);
    

    What's happening is that you are taking the address of a temporary that goes out of scope after the function returns. Subsequent accesses to that memory are undefined behavior.