c++ - 如何解释或缩小此视觉泄漏检测器输出中内存泄漏的原因?

标签 c++ memory-leaks

如何缩小原因范围以找到此 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 39TextureManager() :_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 导致泄漏的输出?这段代码中没有使用 newmalloc 进行直接分配,因为我试图完全转移到 sharedunique pointers。字符串是否可以传递给构造函数并在类中重用和存储问题?从我读到的 std::string 确实管理它自己的内存。

最佳答案

How do I narrow down the cause to find the reason for the memory leak

您可能无意中发现了编译器使用的 STL 实现中的内存泄漏。缩小范围的最佳方法是尽可能多地消除罪魁祸首,并构建一个只使用看似有罪的 unordered_map 什么都不做的 SSCCE 或 MVCE。

#include <memory>
#include <string>
#include <unordered_map>

int main()
{
    std::unordered_map<std::string, std::unique_ptr<std::string>> uomap;  //1

    uomap["hello"] = std::make_unique<std::string>("world");  //2

    return uomap.size() - 1;
}

http://ideone.com/a3hIaj

使用检漏仪启动程序并确定是否仍能看到泄漏。如果你这样做了,恭喜你找到了错误,你会想要将错误报告给你的 STL 供应商。

顺便说一句,如果您使用的是 Microsoft 的实现,您可能会发现有趣的是,unordered_map 的构造涉及许多 malloc。您可以通过在标记为 //1//2 的行上设置断点并启动程序来验证这一点。

当断点 #1 命中时,选择 Debug -> New Breakpoint -> Function Breakpoint 并在 'malloc' 上设置断点。现在按 F5 - 如果您想查看 STL/CRT 中的堆栈跟踪,请选中“Microsoft Symbol Servers”框并单击“确定”。

您会发现仅在 unordered_map 的构造中就有 3-4 次调用 malloc。

关于c++ - 如何解释或缩小此视觉泄漏检测器输出中内存泄漏的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35814384/

相关文章:

c++ - 如何防止为未实现方法的对象生成模板

c++ - c++ 中洪水填充的困难

android - 使用 javah 工具时包含 Android 平台 jar

Python 2.7/Pandas/MySQL 段错误

iphone - Xcode 泄漏工具不起作用

c++ - std::stringstream 如何处理 operator<< 中的 wchar_t*?

java - tomcat shutdown内存泄漏,java线程无法停止

c++ - 为什么这段代码在 C++ 中有内存泄漏

iphone - Objective-c UIImage 存储在 MSMutableArray 替代方案中,潜在的内存泄漏?

c++ - 链表中元素的成对交换(通过改变指针)