了解Microsoft的内存泄漏检测输出
Making sense of Microsoft's Memory Leak Detection output
很抱歉标题不正确,但我只是好奇内存泄漏到底是什么,我怎么能说我在程序中做了一些坏事。
我在Visual Studio中运行了内存泄漏测试(_CrtDumpMemoryLeaks()),它输出了一个检测到的泄漏的巨大列表(只显示了一小部分):
{1640} normal block at 0x081C2AB0, 4 bytes long.
Data: <; > 3B 00 00 00
{789} normal block at 0x08B792E8, 12 bytes long.
Data: < > 00 00 00 00 00 00 00 00 00 00 00 00
{788} normal block at 0x027E62D8, 32 bytes long.
Data: < L L > 20 A8 FE 07 A0 A0 17 08 E4 4C F3 07 D8 4C F3 07
{787} normal block at 0x027E6328, 32 bytes long.
Data: <layer03 - Object> 6C 61 79 65 72 30 33 20 2D 20 4F 62 6A 65 63 74
{786} normal block at 0x08B79748, 8 bytes long.
Data: <`N > 60 4E F3 07 00 00 00 00
我真的不明白,我到底做错了什么。我遵循了我另一个问题的提示,用智能指针替换了所有new/delete
内容(或者至少我认为我做到了)。
我之所以这么问,是因为我在运行程序时遇到了内存大小和堆大小的增加,我不确定这是什么严重的问题还是某种基本行为。
以我的(自写的)gui为例:
std::shared_ptr<Gui_Button> gui_modal_window_map_saved_button;
我现在称之为:
gui_modal_window_map_saved_button.reset(new Gui_Button(res_handler, "Select", 20, 345, 70, 40, BUTTON_CONFIRM));
它被告知是记忆安全的。现在,有一件事我真的不确定——我现在如何安全地删除按钮?我知道,没有什么比智能指针删除更好的了,但我认为删除的方式是在不再需要按钮时删除按钮,即在相应的窗口关闭后。
现在我正在用reset()
"删除"我的按钮
if (g_ev.event_id == EVENT_CLICKED && g_ev.element == gui_modal_window_map_saved_button.get()) {
gui_modal_window_map_saved.reset();
gui_modal_window_map_saved_button.reset();
}
我认为这还可以,但为什么每次创建"新"按钮时,我的内存大小都会增加(而不是再次减少)?
回到最初的问题
我通过Visual Studio得到了这些内存泄漏的转储,但我真的不知道如何使用这些信息。内存泄漏的确切原因是什么?我现在只使用"普通"指针,在那里我需要将一些东西传递给另一个类,即,并用智能指针替换了所有new/deletes
。我真的无法显示我的代码,因为到目前为止大约有3000行。。
那么,究竟是什么导致了内存泄漏,我该如何使用VS提供的信息呢?
Microsoft提供了有关如何利用您看到的数据的详细信息:https://msdn.microsoft.com/en-us/library/x98tx3cf.aspx
可以使用分配编号在进行分配时插入代码。在调试输出的以下行中:
{789} normal block at 0x08B792E8, 12 bytes long.
789是分配编号。你提到内存的使用正在增长。这并不一定意味着泄漏不断增加,除非在执行更长会话时泄漏消息相应增加。
另一件需要考虑的事情是,泄漏发生在您的类中。如果您的对象中分配了任何未正确处理的元素,则没有智能指针可以保存您。
C++与许多较新语言的不同之处在于,它没有所谓的垃圾收集器。您使用new
分配(声明)内存,并使用delete
再次显式解除分配(释放)内存。
如果忘记了delete
,则只有在程序存在后,操作系统才会释放内存。
为了平衡new
和delete
的使用,如果可能的话,只在构造函数中分配内存,并在(虚拟)析构函数中解除分配。通过这种方式,如果拥有一块堆内存(用new
分配的内存)的对象超出范围(例如,在离开函数时是一个局部变量),则该内存将自动释放。
顺便说一句,以这种方式分配和释放内存是赋予C++多功能性和速度的因素之一。因此,这是一种资产,而不是需要避免的东西。但它需要小心使用。
- 递归函数计算序列中的平方和(并输出过程)
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- C++:将控制台输出存储在宏中更好吗
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 使用CMake检测支持的C++标准
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 为什么我的代码在输出中增加了93天
- Visual Studio Code输出被检测为恶意软件?
- OpenCV程序的输出在未检测到文本对象时不给出0
- 了解Microsoft的内存泄漏检测输出
- 如何检测到插入/输出Oculus触摸控制器
- 在Google UnitTest中检测glog输出
- 从WinPE检测BIOS:遗留或UEFI,使用vbs //将结果从.exe输出到.txt
- glibc上valgrind的输出在C++中检测到错误
- Glibc检测到*** ./a.输出:munmap_chunk():无效指针
- MSVC2015中SFINAE成员检测输出错误
- *** glibc检测到***{二进制路径}:双空闲或损坏(输出):0x0000000000639310 ***
- 检测语音合成库的音频输出+建议
- 检测圆括号,括号和大括号是否平衡的c++程序-需要在错误下输出插入符号