调用析构函数时读取0xFEFE时出错 我为一个快板位图做了一个C++包装。我创建一个AguiBitmap作为测试的全局变量,然后我说 bitmap = AguiBitmap("somepath");

调用析构函数时读取0xFEFE时出错 我为一个快板位图做了一个C++包装。我创建一个AguiBitmap作为测试的全局变量,然后我说 bitmap = AguiBitmap("somepath");,c++,C++,在allegro初始化之后 但是,当我关闭应用程序时,它会在位图的析构函数中崩溃。如果我销毁位图(0);这很好,但是我的位图指针不会有任何问题,因为我用它来渲染 AguiBitmap::~AguiBitmap() { al_destroy_bitmap(nativeBitmapPtr); } AguiBitmap::AguiBitmap() { nativeBitmapPtr = 0; width = 0; height = 0; } AguiBit

在allegro初始化之后

但是,当我关闭应用程序时,它会在位图的析构函数中崩溃。如果我销毁位图(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;
}

谢谢

< p>如果你使用VisualC++,Windows调试堆会用<代码> 0xFE内存模式覆盖空闲内存,以帮助调试内存问题。 您已经释放了某些内容,并且(a)您正在尝试访问该内容,或者(b)您正在尝试再次释放该内容


由于您的类手动管理资源,并且由于您不显示复制构造函数和复制赋值操作符实现,请确保您遵循.

,如果使用Visual C++,Windows调试堆将用<代码> 0xFE内存模式覆盖释放的内存,以帮助您调试内存问题。 您已经释放了某些内容,并且(a)您正在尝试访问该内容,或者(b)您正在尝试再次释放该内容


由于您的类手动管理资源,并且您没有显示复制构造函数和复制赋值运算符的实现,因此请确保您遵循了。

Allegro是否在
main
中关闭?如果是这样,那么当全局销毁在
main
之后执行时,我怀疑
al_destroy\u位图
应该失败

就像詹姆斯说的,你打破了三的规则;这可能起到了一定的作用。这
bitmap=AguiBitmap(“somepath”)
将调用
al_destroy_位图(nativeBitmapPtr)当临时工死亡时;这是否会使
位图
的指针不正确



除了这个问题,为什么构造函数有一个
char*
重载?真讨厌。C风格的cast就像一个
常量cast
,这应该是一个错误的提示<代码>标准::字符串
无论如何都可以从文本初始化,所以我不确定为什么您甚至有两个。只要一个,不要丢掉任何常数

Allegro是否在
main
中关闭?如果是这样,那么当全局销毁在
main
之后执行时,我怀疑
al_destroy\u位图
应该失败

就像詹姆斯说的,你打破了三的规则;这可能起到了一定的作用。这
bitmap=AguiBitmap(“somepath”)
将调用
al_destroy_位图(nativeBitmapPtr)当临时工死亡时;这是否会使
位图
的指针不正确



除了这个问题,为什么构造函数有一个
char*
重载?真讨厌。C风格的cast就像一个
常量cast
,这应该是一个错误的提示<代码>标准::字符串
无论如何都可以从文本初始化,所以我不确定为什么您甚至有两个。只要一个,不要丢掉任何常数

您尚未定义复制构造函数(编辑:或复制赋值运算符)

该行构造了一个临时
AguiBitmap
,用于分配位图,然后分配给
bitmap
变量,临时文件被销毁,释放位图。因此,在此行之后使用
位图
是无效的


编辑:具体来说,当
位图
超出范围时,将为第二个对象调用析构函数,并再次删除相同的位图。

您尚未定义复制构造函数(编辑:或复制赋值运算符)

该行构造了一个临时
AguiBitmap
,用于分配位图,然后分配给
bitmap
变量,临时文件被销毁,释放位图。因此,在此行之后使用
位图
是无效的


< > > >编辑< /强>:具体地说,当代码>位图超出范围时,调用第二对象的析构函数,同样的位图被再次删除。< /P>我应该如何构造我的复制构造器?@ MILO:解释正确的C++内存管理、对象生存期以及与实现资源拥有容器相关的问题。具体来说,我建议阅读Habor萨特的特殊C++。第8-19项和第35-41项深入讨论了该主题。该行调用复制赋值运算符,而不是复制构造函数。我将如何为此创建复制构造函数?Thanks@Milo:在这种情况下,我个人会选择不可复制的类。将复制构造函数和复制赋值运算符声明为private,但不定义它们。这将防止这里发生的那种错误。你可以在这个习惯用法上多读一些:我应该如何制作我的副本构造函数?@ MILO:解释正确的C++内存管理,对象生命周期,以及与实现资源拥有容器相关的问题。具体来说,我建议阅读Habor萨特的特殊C++。第8-19项和第35-41项深入讨论了该主题。该行调用复制赋值运算符,而不是复制构造函数。我将如何为此创建复制构造函数?Thanks@Milo:在这种情况下,我个人会选择不可复制的类。将复制构造函数和复制赋值运算符声明为private,但不定义它们。这将防止这里发生的那种错误。您可以阅读有关此成语的更多信息:
bitmap = AguiBitmap("somepath");