Why do I get an access violation exception after deleting the objects from a list?

0

I have to program a videogame for university in C++ using inheritance. For that, I was told to make a state machine with a stack to store the states. I have a class for every different state, all inheriting from a parent class, "GameState". GameState has a list of GameObjects, another list of EventHandlers, and a pointer to the SDL application.

I have no problem when popping most GameStates from the stack, but when I try to pop PlayState, in which the proper game takes place, I get an access violation exception.

I'm using std::list and std::stack

The error is probably something in GameStateMachine.cpp and GameState.cpp, but I'm attaching more related code for good mesure. If it is too much I'll make another, shorter submission.

Exception message:

Exception produced in 0x0044B7D2 in HolaSDLDebug.exe: 0xC0000005: 
Access violation when writing to location 0xDDDDDDDD.

Exception takes place on file xmemory, line 1287:

// MEMBER FUNCTIONS FOR _Container_base12
inline void _Container_base12::_Orphan_all() noexcept {
#if _ITERATOR_DEBUG_LEVEL == 2
    if (_Myproxy) { // proxy allocated, drain it
        _Lockit _Lock(_LOCK_DEBUG);

        for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
            (*_Pnext)->_Myproxy = nullptr;
        }

        _Myproxy->_Myfirstiter = nullptr;
    }
#endif // _ITERATOR_DEBUG_LEVEL == 2
}

GameStateMachine.h:

#pragma once
#include "GameState.h"
#include <stack>

class GameStateMachine 
{
private:
    stack<GameState*> stateStack;
    string flag = "";
public:
    GameState* currentState();
    void pushState(GameState* state);
    void changeState(GameState* state);
    void popState();
    void setFlag(string thisFlag);
    string getFlag();
};

GameStateMachine.cpp:

#include "GameStateMachine.h"

void GameStateMachine::changeState(GameState* state)
{
    popState();
    pushState(state);
}

void GameStateMachine::pushState(GameState* state)
{
    stateStack.push(state);
}

GameState* GameStateMachine::currentState()
{
    return stateStack.top();
}

void GameStateMachine::popState()
{
    delete stateStack.top();
    stateStack.pop();
}

void GameStateMachine::setFlag(string thisFlag) 
{
    flag = thisFlag;
}

string GameStateMachine::getFlag()
{
    return flag;
}

GameState.h:

#pragma once
#include <list>
#include "GameObject.h"
#include "EventHandler.h"
#include "Texture.h"
#include "Constants.h"
#include <string>

class SDLApplication;

class GameState 
{
protected:
    list<GameObject*> objects;
    list<EventHandler*> events;
    SDLApplication* game;
public:
    GameState(SDLApplication* game);
    ~GameState();
    virtual void update() = 0;
    virtual void render() = 0;
    virtual void handleEvents() = 0;
    virtual void saveToFile();
    virtual void loadFromFile();
    void exitGame();
    bool getExit();
    Texture* getTexture(int num);
    void Pause();
    void Resume();
    void End();
};

GameState.cpp:

#include "SDLApplication.h"
#include "GameState.h"

GameState::GameState(SDLApplication* game) : game(game) {}

GameState::~GameState() 
{
    for (GameObject* ob : objects)
    {
        delete ob;
    }
};

void GameState::exitGame()
{
    game->exitGame();
}

bool GameState::getExit()
{
    return game->getExit();
}

Texture* GameState::getTexture(int num)
{
    return game->getTexture(num);
}

void GameState::loadFromFile()
{
    game->loadFromFile();
}

void GameState::saveToFile()
{
    game->saveToFile();
}

void GameState::Pause() {
    game->Pause();
}

void GameState::Resume() {
    game->Resume();
}

void GameState::End() {
    game->End();
}

PlayState.h:

#pragma once
#include "GameState.h"
#include "Balloon.h"
#include "Arrow.h"
#include "Reward.h"
#include "Butterfly.h"
#include "ScoreBoard.h"
#include "Bow.h"
#include <vector>
#include "Constants.h"
#include "FileFormatError.h"
#include "FileNotFoundError.h"
#include "SDLError.h"


class PlayState : public GameState 
{
private:
    list<Arrow*> shotArrows;
    list<list<GameObject*>::iterator> objectsToErase;
    bool saving = false;
    int availableArrows = BASE_ARROWS_AMOUNT;
    int currentButterflies = 0;
    int currentArrows = 0;
    int points = 0;
    int currentMap = 0;
    int currentMaxPoints = BASE_POINT_MAX;
    bool load = false;
    string file = "";
public:
    PlayState(SDLApplication* game, bool load, string file);
    virtual void update();
    virtual void render();
    virtual void handleEvents();
    virtual void saveToFile();
    void loadFromFile(string file);
    Arrow* collision(ArrowsGameObject* obj, int cols, int rows);
    void shoot(Arrow* arrow);
    int changeScore(int value);
    void rewardspawner(Point2D rewardPosition, Arrow* arrow);
    void balloonspawner();
    void butterflySpawner();
    void killObject(list<GameObject*>::iterator object);
    void updateButterflyCounter();
    int changeAvaliableArrows(int amount);
    int changeCurrentArrows(int amount);
};
c++
list
inheritance
asked on Stack Overflow Jan 19, 2020 by TLyon

1 Answer

0

I'd suggest getting used to breakpoints and general debugging. This issue can be tracked down manually: set a breakpoint on popState() function. When it gets hit, examine the stack trace and look for something odd.

I'd bet that the whole function is wrong. This line: delete stateStack.top(); is suspicious to me. The function top() is for looking at the top element, it's not meant for managing the element underneath.

P.S. For the university's course, you'd better use "C with classes" style approach, and not mix it with C++. Either you tell people to use modern C++ approach or bite the bullet and use dreaded "C with classes".

answered on Stack Overflow Jan 19, 2020 by login_not_failed

User contributions licensed under CC BY-SA 3.0