0xC0000005:析构函数中的访问冲突读取位置错误

问题描述 投票:0回答:2

我有一个类,用于将图像文件加载到位图并保持对这些位图的引用。我希望稍后在关闭应用程序之前解除这些资源的释放。

所以我的班级(是一个单身人士)设计如下:

class ImageManager
{
public:
   static ImageManager &getInstance();
   ImageManager(ImageManager const&) = delete;
   void operator=(ImageManager const&) = delete;
   void loagImage(char *location);
   ~ImageManager();
private:
   ImageManager();
   ALLEGRO_BITMAP *image = nullptr;
}

真正的构造函数中没有什么。只需加载与处理位图相关的附加组件。没有创建原始指针。

loadImage()实现如下:

void ImageManager::loadImage(char *location)
{
    if(!location)
    {
       throw std::invalid_argument("Location cannot be null.");
    }
    image = al_load_bitmap(location);
}

析构函数定义为

ImageManager::~ImageManager()
{
   if(image)
   {
       al_destroy_bitmap(image); // Here I get the access violation exception.
   }
}

这个类在main.cpp中的使用方式如下:

int main(int argc, char *args[])
{
    ImageManager &imgManager = ImageManager::getInstance();
    imgManager.loadImage("valid/location");

    return 0;
}

如果我在加载位图的相同函数中调用al_destroy_bitmap(),则没有错误。它只发生在我尝试在析构函数中调用它时。

我在使用VS17的Windows 10上。我在同一个主题上看到了很多问题,但我无法使用那里的答案找出错误。如果您需要,我还会链接到两个allegro方法:

  1. al_load_bitmap()
  2. al_destroy_bitmap()

编辑:

我的getInstance()方法是:

ImageManager &ImageManager::getInstance()
{
    static ImageManager instance;
    return instance;
}

编辑2:

确切的错误是0xC0000005: Access violation reading location 0xDDDDDDF1.

pointers c++14 allegro5
2个回答
1
投票

Allegro 5不像单身人士这样的全局游戏。

要记住的事情:

1)在调用al_init之前发生全局对象或静态初始化的全局调用。这意味着在其构造函数内调用allegro函数将失败。

2)全球静力学主力和主力。这意味着他们的析构函数将在allegro通常关闭后运行。 al_install_system挂钩atexit关闭它的库,除非你明确告诉它不要。这意味着如果你很幸运的话,对像al_destroy_bitmap这样的快板功能的调用会失败并且会发生段错误。

在调用al_uninstall_system之前,在atexit和main退出之前或之前,你必须明确地“关闭”你的ImageManager实例。


0
投票

instance更改为指针,让getInstance创建一个实例,并在destroyInstance之前添加显式return 0调用来删除实例,因为在退出main之后你不再拥有一个不受你控制的破坏/释放序列。

© www.soinside.com 2019 - 2024. All rights reserved.