我为allegro位图制作了一个c ++包装器。我创建一个AguiBitmap作为测试的全局变量,然后我说,
bitmap = AguiBitmap("somepath");
在allegro初始化之后。
但是,当我关闭应用程序时,它会在位图的析构函数中崩溃。如果我做al_destroy_bitmap(0);它很好,但我的位图指针不能出错,因为我用它来渲染。
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;
}
由于
答案 0 :(得分:3)
您尚未定义复制构造函数(编辑:或复制赋值运算符)。
bitmap = AguiBitmap("somepath");
该行构造一个临时AguiBitmap
,它分配位图,然后分配给bitmap
变量,临时被销毁,释放位图。因此,在此行之后使用bitmap
无效!
编辑:具体而言,当bitmap
超出范围时,将为第二个对象调用析构函数,并再次删除相同的位图。
答案 1 :(得分:2)
如果您使用的是Visual C ++,则Windows调试堆会使用0xfe
内存模式覆盖释放的内存,以帮助您调试内存问题。
你已经释放了一些东西,或者(a)你试图访问那个东西,或者(b)你试图再次释放那个东西。
由于您的类手动管理资源,并且由于您没有显示复制构造函数和复制赋值运算符实现,因此请确保您遵循rule of three。
答案 2 :(得分:1)
Allegro是否在main
关闭?如果是这样,那么当全局在 main
之后破坏时,我怀疑al_destroy_bitmap
应该失败。
就像詹姆斯所说,你打破了三个人的统治;这可能发挥了作用。当临时死亡时,bitmap = AguiBitmap("somepath");
会调用al_destroy_bitmap(nativeBitmapPtr);
;这会使bitmap
出现错误的指针吗?
除了这个问题,为什么你的构造函数有char*
重载?那太讨厌了。 C风格的演员表现得像const_cast
,这应该是一个提示错误的提示。 std::string
无论如何都可以从文字初始化,所以我不确定为什么你有两个。只有一个,不要抛弃任何常量。