c++ – Getting error reading from 0xfefefefe when destructor is called – Education Career Blog

I have made a c++ wrapper for an allegro bitmap. I create an AguiBitmap as a global variable for testing, then later I say,

bitmap = AguiBitmap("somepath");

after allegro has been initialized.

However, when I close the application, it crashes in the bitmap’s destructor. If I do al_destroy_bitmap(0); its fine, but there cant be anything wrong with my bitmap pointer because I use it to render.

AguiBitmap::~AguiBitmap()
{
        al_destroy_bitmap(nativeBitmapPtr); 
}

AguiBitmap::AguiBitmap()
{
    nativeBitmapPtr = 0;
    width = 0;
    height = 0;
}

AguiBitmap::AguiBitmap( char *filename )
{

    if(!filename)
    {
        nativeBitmapPtr = 0;
        return;
    }

    nativeBitmapPtr = al_load_bitmap(filename);

    if(nativeBitmapPtr)
    {

        width = al_get_bitmap_width(nativeBitmapPtr);
        height = al_get_bitmap_height(nativeBitmapPtr);
    }
    else
    {
        width = 0;
        height = 0;
    }
}

AguiBitmap::AguiBitmap( std::string filename )
{
    AguiBitmap((char*)filename.c_str());
}

ALLEGRO_BITMAP* AguiBitmap::getBitmap() const
{
    return nativeBitmapPtr;
}

int AguiBitmap::getWidth() const
{
    return width;
}

int AguiBitmap::getHeight() const
{
    return height;
}

Thanks

,

You have not defined a copy constructor (edit: or copy-assignment operator).

bitmap = AguiBitmap("somepath");

That line constructs a temporary AguiBitmap which allocates the bitmap, then assigns to bitmap variable and the temporary is destroyed, releasing the bitmap. Therefore, any use of bitmap after this line is invalid!

Edit: specifically, when bitmap goes out of scope, the destructor is invoked for the 2nd object and the same bitmap is deleted again.

,

If you are using Visual C++, the Windows debug heap overwrites freed memory with the 0xfe memory pattern to help you to debug memory issues.

You’ve freed something and either (a) you are trying to access that thing or (b) you are trying to free that thing again.

Since your class manually manages resources, and since you don’t show the copy constructor and copy assignment operator implementations, make sure you are following the rule of three.

,

Is Allegro being shut down in main? If so, then when the global destructs after main, I suspect al_destroy_bitmap should fail.

And like James says, you’re breaking the rule of three; this probably plays a role. This bitmap = AguiBitmap("somepath"); will call al_destroy_bitmap(nativeBitmapPtr); when the temporary dies; does this leave bitmap with a bad pointer?


Aside from the question, why do you have a char* overload of the constructor? That’s nasty. The C-style cast is acting like a const_cast, that should be a hint something is wrong. std::string can initialize from literals anyway, so I’m not sure why you even have two. Just have one, and don’t cast any const’s away.

Leave a Comment