【发布时间】:2016-03-05 12:54:15
【问题描述】:
如何缩小原因以找到此 Visual Leak Detector 输出中报告的内存泄漏的原因?
问题不是为我调试这个特定的代码,而是如何解决这样的问题。 Visual Leak Detector 报告了许多泄漏,并且此类问题在 SO 上非常常见,因此我希望得到一个不那么具体但更笼统的答案,以便它不仅在这种特殊情况下有所帮助,而且对其他人也有更多帮助。
---------- Block 305 at 0x00000000FCBFBBB0: 64 bytes ----------
Leak Hash: 0x7DAD966C, Count: 1, Total 64 bytes
Call Stack (TID 11728):
ucrtbased.dll!malloc()
e:\programme (x86)\microsoft visual studio 14.0\vc\include\xmemory0 (901): Shady.exe!std::_Wrap_alloc<std::allocator<std::_List_node<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::unique_ptr<Texture,std::default_delete<Texture> > >,void * __ptr64> > >::allocate()
e:\programme (x86)\microsoft visual studio 14.0\vc\include\list (730): Shady.exe!std::_List_alloc<std::_List_base_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::unique_ptr<Texture,std::default_delete<Texture> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,st() + 0x19 bytes
e:\programme (x86)\microsoft visual studio 14.0\vc\include\list (716): Shady.exe!std::_List_alloc<std::_List_base_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::unique_ptr<Texture,std::default_delete<Texture> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,st()
e:\programme (x86)\microsoft visual studio 14.0\vc\include\list (631): Shady.exe!std::_List_alloc<std::_List_base_types<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::unique_ptr<Texture,std::default_delete<Texture> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,st() + 0xC bytes
e:\programme (x86)\microsoft visual studio 14.0\vc\include\list (818): Shady.exe!std::_List_buy<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::unique_ptr<Texture,std::default_delete<Texture> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > con()
e:\programme (x86)\microsoft visual studio 14.0\vc\include\list (896): Shady.exe!std::list<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::unique_ptr<Texture,std::default_delete<Texture> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,s()
e:\programme (x86)\microsoft visual studio 14.0\vc\include\xhash (197): Shady.exe!std::_Hash<std::_Umap_traits<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::unique_ptr<Texture,std::default_delete<Texture> >,std::_Uhash_compare<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::hash<std() + 0x1A bytes
e:\programme (x86)\microsoft visual studio 14.0\vc\include\unordered_map (119): Shady.exe!std::unordered_map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::unique_ptr<Texture,std::default_delete<Texture> >,std::hash<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::equal_to<std::basic_string()
e:\repositories\shady\src\texture\texturemanager.h (39): Shady.exe!TextureManager::TextureManager() + 0x44 bytes
e:\repositories\shady\src\engine.h (53): Shady.exe!Engine::Engine() + 0x65 bytes
e:\repositories\shady\src\engine.cpp (97): Shady.exe!main() + 0x1D bytes
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (75): Shady.exe!invoke_main()
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (264): Shady.exe!__scrt_common_main_seh() + 0x5 bytes
f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (309): Shady.exe!__scrt_common_main()
f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): Shady.exe!mainCRTStartup()
KERNEL32.DLL!BaseThreadInitThunk() + 0x22 bytes
ntdll.dll!RtlUserThreadStart() + 0x34 bytes
Data:
B0 BB BF FC B4 01 00 00 B0 BB BF FC B4 01 00 00 ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD ........ ........
engine.cpp 97 是Engine engine = Engine();,它构造了这个类的一个对象
class Engine{
Engine() : _logger("Engine"){}
TextureManager _textureManager;
Logger mutable _logger;
};
而texturemanager.h 39 是此类的TextureManager() :_logger("TextureManager"){};:
class TextureManager{
TextureManager() :_logger("TextureManager"){};
~TextureManager() {
for (const auto& kv : _textures) {
GLuint h = kv.second->getTextureHandle();
glDeleteTextures(1, &h);
}
}
std::unordered_map<std::string, std::unique_ptr<Texture>> _textures;
Logger mutable _logger;
};
我是否正确理解 unordered_map 导致泄漏的输出?当我尝试完全移至shared 和unique pointers 时,此代码中没有涉及new 或malloc 的直接分配。传递给构造函数并重用并存储在类中的字符串是否存在问题?从我读到的 std::string 确实管理它自己的内存。
【问题讨论】:
-
您的记录器中有
unordered_map吗?如果是这样,如何清理? -
否,但上面的 TextureManager 有一个无序的贴图。我没有清理 unordered_map 本身,因为我希望它能够被正确清理,还是我错了?
-
假设您的
TextureManager本身已被销毁(这可能在Engine被销毁时发生,那么unordered_map也应该被清理。 -
您使用的是哪个编译器/STL?可能值得创建一个简单的程序,它有一个
std::unordered_map<std::string, std::unique_ptr<char>>,您可以在其中填充一些条目然后退出,例如 ideone.com/a3hIaj -
我试过这个kfsone,它没有泄漏。我正在使用 Visual Studio 2015。
标签: c++ memory-leaks