我使用Visual Studio 2017和Allegro 5在C ++中制作游戏。当我使用_CrtDumpMemoryLeaks()
检查内存泄漏时,我在启动游戏然后从标题屏幕关闭时发现两个泄漏。当我浏览标题屏幕时会发生更多泄漏,但我想先解决这些问题,以防它们相关。在我的主要游戏循环之后,我已将泄漏追踪到一条线:ImageLoader::get_instance().unload_content()
。当我在泄漏位置为内存分配设置断点时,我看到了这个调用堆栈:
Game1.exe!operator new(unsigned int size) Line 19
Game1.exe!std::_Allocate(unsigned int _Count, unsigned int _Sz, bool _Try_aligned_allocation) Line 87
...
Game1.exe!ImageLoader::ImageLoader() Line 5
Game1.exe!ImageLoader::get_instance() Line 17
Game1.exe!main() Line 103
ImageLoader的第5行是image_map = std::map<std::pair<std::string, std::string>, ALLEGRO_BITMAP*>()
。图像映射在ImageLoader.h中声明如下:std::map<std::pair<std::string, std::string>, ALLEGRO_BITMAP*> image_map
。 ImageLoader::get_instance()
是一个返回ImageLoader实例的静态方法:
ImageLoader & ImageLoader::get_instance()
{
static ImageLoader loader;
return loader;
}
我目前创建ImageLoader实例的唯一地方是我之前提到的unload_content()
调用,其中泄漏来自。 (显然这意味着在这种特定情况下调用是不必要的,但我已经测试了更快地调用get_instance()
并且由于创建了静态ImageLoader对象而发生同样的问题。在任何一种情况下,我都看到相同的两个内存泄漏。)虽然image_map
的创建似乎是泄漏的来源,但在程序运行的整个过程中它都是空的。解除分配为地图保留的内存的正确方法是什么?
编辑:
以下是我尝试为图像映射释放内存的unload_content
方法:
void ImageLoader::unload_content()
{
for (auto const &it : image_map) {
al_destroy_bitmap(it.second);
}
我的程序当前设置方式,没有元素插入到地图中 - 创建的ImageLoader的唯一实例位于行ImageLoader::get_instance().unload_content()
中。虽然我的游戏确实有一个主循环,但我从不在循环中调用ImageLoader::get_instance()
或ImageLoader中的任何其他函数。
编辑2:
在我的主游戏循环之后,这是unload_content()
调用的上下文:
{
ImageLoader::get_instance().unload_content();
ScreenManager::get_instance().unload_content();
al_destroy_display(display);
al_destroy_timer(timer);
al_destroy_event_queue(event_queue);
}
_CrtDumpMemoryLeaks();
return 0;