Error when destroying bitmap images

Started by
6 comments, last by EWClay 11 years, 1 month ago

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);
}

Advertisement
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.

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.

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

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);
}

Dan Mayor

Professional Programmer & Hobbyist Game Developer

Seeking team for indie development opportunities, see my classifieds post

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.

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;
}

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.

This topic is closed to new replies.

Advertisement