VS2010 Unhandled exception on allegro_exit()

  allegro4, c++, oop

For some reason I get an unhandled exception every time I try to exit my program. Visual studio breaks at allegro_exit() each time and throws the following:
First-chance exception at 0x67F2884B (allegro-4.4.2-md.dll) in TMA2.exe: 0xC0000005: Access violation reading location 0xFEEEFEFE.

Now here is the weird part which is driving me crazy, just before the end of my program I call destroy_bitmap(buffer); as is good programming practice, I also call a destroy function that destroys the bitmaps I have stored in one of my objects. For some reason, if I remove the destroy_bitmap(buffer); statement just before allegro_exit() I no longer experience the error. I cannot figure out why this would be the case for the life of me. Can anyone maybe shed some light on what is happening here for me? Honestly I have been avoiding this problem for weeks because I have spent hours trying to figure this out myself with no luck. I am still learning C++ so I am sorry if this is something obvious but I am at wits end.

I am unsure if this is related but I am also experiencing crashing in my changeSelection method for my Menu object. In the below code I have commented out this function call (see "option.changeSelection(buffer);"). When run without calling this method (commented out as below) the program doesn’t crash until I try to exit and then the error I have specified above occurs. I am hoping it is only crashing because of whatever is causing the above error and once I fix this I will be able to reinstate the method call.

I tried changing the pointer to a const pointer (as seen below) so that I could ensure the memory address of the buffer was not changing when it shouldn’t be. This did not fix the issue or halt my program anywhere different, the same error occurs so it shouldnt be a problem with the pointer address for the buffer. I tried changing the way my buffer was passed around to pass by reference for all functions (previously it was passed by pointer) and this also did not help the issue. I changed the location of my static variables declared in main to being declared after allegro_init() (which enabled me to initialize the const pointer for buffer) but this also had no effect. I am getting very frustrated trying to debug this problem because I am also experiencing an issue with visual studio where, when the break occurs, my mouse and keyboard input for my laptop lag like CRAZY. VS becomes unusable and I have to hit enter to break and then shift+f5 to stop debugging so my input goes back to normal. This is really frustrating me and making debugging difficult, I have tried to look up how to fix the issue and found some information saying this was related to the DirectInput keyboard and mouse handlers, but unfortunately I know exactly zip about DirectX and I have no idea how to fix this issue.

The following is my main code and my header, please let me know if you need to see more functions.

int main(void)
{
    //initialize program 
    allegro_init();
    set_color_depth(24);
    if((set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0)) < 0) {
        allegro_message("Error initializing graphics: %s", allegro_error);
    }
    install_keyboard();
    install_mouse();
    install_timer();
    srand(time(NULL));

    //initialize static variables
    BITMAP *tiles[6] = {NULL};
    BITMAP *ant[4] = {NULL};
    BITMAP * const buffer = create_bitmap(640, 480);
    SPRITE antSprite;
    Menu option;
    Graph map;
    SPRITE::coord dir;

    option.init();                      //initialize menu
    set_mouse_sprite(NULL);             //initialize mouse sprite
    loadTiles(tiles);                   //load terrain tile bitmaps
    loadSprite(ant, antSprite);

    clear_to_color(buffer, BLACK);
    
    //display title
    textout_ex(buffer,font,"Ant Game",2,1,WHITE,0);
    
    //main game loop
    while (!key[KEY_ESC])
    {
        //see if mouse needs polled before using mouse position functions
        if(mouse_needs_poll())
        {
            poll_mouse();
        }
        //change menu selection
        //option.ChangeSelection(buffer);
        //get and apply player input
        getInput(option, map);

        //cleanup old sprite anim before drawing anything 
        rectfill(buffer, antSprite.old_pos.x, antSprite.old_pos.y, 
                        antSprite.old_pos.x+antSprite.width, antSprite.old_pos.y+antSprite.height, BLACK);

        //draw the menu and the tile grid
        option.DrawMenu(*buffer);
        drawMap(tiles, map, *buffer);
        drawGrid(buffer);

        if(allSet && startSet && goalSet)
        {
            allegro_message("All the tiles are set! hit okay when you're ready");
            draw_sprite(buffer, ant[antSprite.curframe], antSprite.pos.x, antSprite.pos.y);
            updateSprite(antSprite);
            dir = antSprite.seek(SCREEN_W/2, SCREEN_H/2);
            antSprite.move(dir);
        }

        show_mouse(buffer);

        //update the screen
        blit(buffer, screen, 0, 0, 0, 0, 640, 480);

        //game timer 
        rest(10);
    }
    //cleanup
    option.Destroy();
    destroy_bitmap(buffer);

    allegro_exit();
    return 0;
}
END_OF_MAIN()

The header

#ifndef ANTGAME_H
#define ANTGAME_H

#ifndef ALLEGRO_H
#define ALLEGRO_H
#include<allegro.h>
#endif

#ifndef VECTOR_H
#define VECTOR_H
#include<vector>
#endif

//Some colours
#define WHITE makecol(255, 255, 255)
#define BLACK makecol(0, 0, 0)
#define RED makecol(255, 0, 0)
#define ORANGE makecol(255, 175, 28)
#define BLUE makecol(0, 0, 255)

const int tileSz = 30;

enum Terrain {obstacle, openland, grass, swamp, start, goal};

struct Node {
    //identify node by its characteristic point
    //should be sufficient for our simple game
    float nodex, nodey;
    Terrain terrain;
    int graphIndex;

    bool set;
    Node();
};

struct Connection   {
    float cost;
    Node fromNode;
    Node toNode;

    float getCost() { return cost; }
    Node getFromNode()  { return fromNode; }
    Node getToNode()    { return toNode; }
};

struct NodeRecord   {
    Node node;
    Connection connection;
    float costSoFar;
    float estTotalCost;
};

struct Heuristic    {
    Node goalNode;
    float estimate(Node fromNode);
};

struct Graph    {
    static const int tiles = 256;
    Node nodes[tiles];
    Heuristic heuristic;

    std::vector<Connection> getConnections(int index);
    std::vector<Node> pathfindAStar(int start, int end);
};
        
class Menu  {
    BITMAP* pic_open;
    BITMAP* pic_swamp;
    BITMAP* pic_grass;
    BITMAP* pic_obstacle;
    int highltx, highlty, o_highltx, o_highlty;
    int selectx, selecty, o_selectx, o_selecty;
public:
    Terrain current;

    void ChangeSelection(BITMAP *b);
    void DrawMenu(BITMAP &b);
    void init();
    void Destroy();
};

struct SPRITE
{
    struct coord    {
        int x, y;
        void normalize();
    };
    coord pos;                      //track the sprites position
    coord old_pos;
    int width, height;              //set to the size of the sprite image outside the struct
    coord speed;                    //determine how many pixels the sprite will move in conjunction with the velocity delay
    coord delay;                    //allows some sprites to move slower than other sprites
    coord count;
    int curframe, maxframe;         //help the sprite animation and animation delay elements
    int framecount, framedelay;     //slow down the animation rate

    coord seek(int tx, int ty);
    void move(coord velocity);
};
#endif

I will be supremely grateful for any help, please drop all of that knowledge on me I need to learn! Thank you in advance!

Source: Windows Questions C++

LEAVE A COMMENT