Sign in to follow this  
krrice

Error when destroying bitmap images

Recommended Posts

krrice    120

hey everyone, I am getting arror that I can't figure out. I am making a breakout clone and my error is when i exit the game. The error is

 

Unhandled exception at 0x56c807e5,Access violation reading location 0xfeef001a

 

  /*
         * The /GS security cookie must be initialized before any exception
         * handling targetting the current image is registered.  No function
         * using exception handling can be called in the current image until
         * after __security_init_cookie has been called.
         */
        __security_init_cookie();

        return __tmainCRTStartup();
}

 

I know it has something to do with destroying the bitmap images for my bricks because I can comment out the destroy bitmap code and no errors .

 

in main this is the code for generating the bricks:

 

for(int x = 0; x < bricksWide; x++)
        {
            Brick *brick = new Brick(brickImage, x * al_get_bitmap_width(brickImage), y * al_get_bitmap_height(brickImage), tint);
            brickObj.push_back(brick);
        }

 

and at the end of main this is the code for destroying the bitmaps:

 

for(iter = brickObj.begin(); iter != brickObj.end(); )
    {
        (*iter)->Destroy();
        delete (*iter);
        iter = brickObj.erase(iter);
    }

 

and my Destroy() function in my Brick class is:

 

void Brick::Destroy()
{
    if(image != NULL)
        al_destroy_bitmap(image);
}

 

 

Share this post


Link to post
Share on other sites
SiCrane    11839
0xFEEEFEEE is the memory fill pattern that MSVC uses for freed memory with the debug heap. If you see an access violation in that area it generally means you've messed with memory that you've already deallocated. The first thing I'd look at is your Brick destructor.

Share this post


Link to post
Share on other sites
krrice    120

0xFEEEFEEE is the memory fill pattern that MSVC uses for freed memory with the debug heap. If you see an access violation in that area it generally means you've messed with memory that you've already deallocated. The first thing I'd look at is your Brick destructor.

 

My Brick Destructor is empty.

Share this post


Link to post
Share on other sites
Digivance    1724

You create the pointer / dynamic memory within the first for loop and your trying to delete it outside of the scope.  Your deleting a pointer to a pointer to a dynamic memory address.  This can not be done in C++ to call delete on the original pointer that references the dynamic memory.  In other words, stop using pointers, what you are doing right now is leaking bad.

 

 

for(int x = 0; x < bricksWide; x++)
        {
            Brick *brick = new Brick(brickImage, x * al_get_bitmap_width(brickImage), y * al_get_bitmap_height(brickImage), tint);
            brickObj.push_back(brick);

            // This is the last chance you have to delete brick.
        }

 

// Brick itself is now out of scope and unreachable by code (eg access violation)

and at the end of main this is the code for destroying the bitmaps:

 

for(iter = brickObj.begin(); iter != brickObj.end(); )
    {
        (*iter)->Destroy();

        // delete iter is trying to release the dynamic memory referenced by (*iter) but (*iter) is a pointer to "brick" (which in turn points to the memory)

        // so in other words, "brick" is now in use and you can't do anything about it and "iter" effectively gets you the brick data but can not be deleted.
        delete (*iter);
        iter = brickObj.erase(iter);
    }

 

and my Destroy() function in my Brick class is:

 

void Brick::Destroy()
{
    if(image != NULL)
        al_destroy_bitmap(image);
}

Share this post


Link to post
Share on other sites
EWClay    659

You create the pointer / dynamic memory within the first for loop and your trying to delete it outside of the scope. Your deleting a pointer to a pointer to a dynamic memory address. This can not be done in C++ to call delete on the original pointer that references the dynamic memory. In other words, stop using pointers, what you are doing right now is leaking bad.


for(int x = 0; x < bricksWide; x++)
{
Brick *brick = new Brick(brickImage, x * al_get_bitmap_width(brickImage), y * al_get_bitmap_height(brickImage), tint);
brickObj.push_back(brick);

// This is the last chance you have to delete brick.
}


// Brick itself is now out of scope and unreachable by code (eg access violation)

and at the end of main this is the code for destroying the bitmaps:


for(iter = brickObj.begin(); iter != brickObj.end(); )
{
(*iter)->Destroy();

// delete iter is trying to release the dynamic memory referenced by (*iter) but (*iter) is a pointer to "brick" (which in turn points to the memory)

// so in other words, "brick" is now in use and you can't do anything about it and "iter" effectively gets you the brick data but can not be deleted.
delete (*iter);
iter = brickObj.erase(iter);
}


and my Destroy() function in my Brick class is:


void Brick::Destroy()
{
if(image != NULL)
al_destroy_bitmap(image);
}


That entire post makes no sense. But to the OP, consider using smart pointers in the container, it's safer.

Share this post


Link to post
Share on other sites
krrice    120

It looks like the bricks share an image but you are destroying it for every brick. You should only destroy the brick image once.

 

Thanks , it makes sense now. So at the end of main I need to delete the image like:

 

    delete paddle;
    delete ball;
    al_destroy_bitmap(brickImage);
    //SHELL OBJECTS=================================
    al_destroy_font(font18);
    al_destroy_timer(timer);
    al_destroy_event_queue(event_queue);
    al_destroy_display(display);

    return 0;
}

 

But don' I need to do something in the class for the bitmap pointers I create for each brick;

 

Brick::Brick(ALLEGRO_BITMAP *image,int x,int y, ALLEGRO_COLOR tint)
{
    width = al_get_bitmap_width(image);
    height = al_get_bitmap_height(image);
    this->image = image;
    this->x = x;
    this->y = y;
    this->tint = tint;
    alive = true;
}

Share this post


Link to post
Share on other sites
EWClay    659
No, they are just pointers to the image; they don't own it and don't need to be freed.

The only thing you have to be sure to do is not use them again after the image has been freed.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this