Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 理解微软';内存泄漏检测输出_C++_Visual Studio_Memory Leaks - Fatal编程技术网

C++ 理解微软';内存泄漏检测输出

C++ 理解微软';内存泄漏检测输出,c++,visual-studio,memory-leaks,C++,Visual Studio,Memory Leaks,很抱歉标题不好,但我只是好奇内存泄漏到底是什么,我怎么能说我在程序中做了一些不好的事情 我在Visual Studio中运行了内存泄漏测试(_CrtDumpMemoryLeaks()),它输出了大量检测到的泄漏(只显示了一小部分): 我现在称之为: gui_modal_window_map_saved_button.reset(new Gui_Button(res_handler, "Select", 20, 345, 70, 40, BUTTON_CONFIRM)); 它被告知是内存安全的。

很抱歉标题不好,但我只是好奇内存泄漏到底是什么,我怎么能说我在程序中做了一些不好的事情

我在Visual Studio中运行了内存泄漏测试(_CrtDumpMemoryLeaks()),它输出了大量检测到的泄漏(只显示了一小部分):

我现在称之为:

gui_modal_window_map_saved_button.reset(new Gui_Button(res_handler, "Select", 20, 345, 70, 40, BUTTON_CONFIRM));
它被告知是内存安全的。现在,有一件事我不是很确定——我现在如何安全地删除按钮?我知道,没有什么比使用智能指针删除更好的了,但我想在不再需要按钮时,即在相应的窗口关闭后,通过移除按钮的方式删除

目前,我正在使用
reset()

我认为这没关系,但为什么每次创建“新”按钮时,我的内存大小都在增加(而不是再次减少)

回到原来的问题

我从VisualStudio得到这些内存泄漏转储,但我真的不知道如何使用这些信息。到底是什么导致内存泄漏?我现在只使用“普通”指针,需要将某些内容传递给另一个类,即,用智能指针替换所有
new/deletes
。我真的无法显示我的代码,因为到目前为止大约有3000行


那么,到底是什么导致了内存泄漏,我是如何使用VS提供的信息的呢

Microsoft提供了有关如何利用您看到的数据的详细信息:

在进行分配时,可以使用分配号打断代码。在调试输出的以下行中:

{789}0x08B792E8处的正常块,12字节长。

789是分配号。您提到内存使用正在增长。这并不一定意味着泄漏的增加,除非在执行更长会话时泄漏消息相应增加


另外要考虑的是,泄漏发生在你的班级里。如果在您的对象中分配的任何元素没有被正确处理,那么智能指针将无法拯救您。

C++与许多新语言的不同之处在于它没有所谓的垃圾收集器。您使用
new
分配(声明)内存,并使用
delete
再次显式取消分配(释放)内存

如果忘记了删除,则只有在程序存在后,操作系统才会释放内存

要平衡使用
new
和使用
delete
,请尽可能只在构造函数中分配内存,并在(虚拟)析构函数中取消分配内存。这样,如果拥有一块堆内存(使用
new
分配的内存)的对象超出范围(例如离开函数时的局部变量),内存将自动释放


顺便说一下,以这种方式分配和释放内存是C++的通用性和速度之一。因此,这是一种资产,而不是需要避免的东西。但它需要小心使用。

这是一个一般性问题?内存泄漏与硬件无关,除非你将笔记本电脑留在雨中…灰色区域。我认为内存泄漏是一个普遍的问题。还有更多的“我现在只使用“普通”指针,在这里我需要将一些东西传递给另一个类”-听起来你应该使用引用来代替。是的,这是我学到的。但是,如果我不显式地调用new,那么我就不会遇到任何问题,不是吗?事实上,你不应该。在其他一些回答中,我读到我可能调用_CrtDumpMemoryLeaks();在不合适的地方。目前,我已经将它放在程序结束之前(返回0;)也许您可以通过这种方式诊断问题,但是如果您的设计需要它,您就有问题了。最好遵守构造函数/析构函数规则,通常被称为“构造就是资源分配”,“销毁就是资源释放”。顺便说一句,资源也可以是打开的文件、信号量和类似的东西。@JacquesDehoge:通常情况下,这是很糟糕的,因为标准库容器和
std::unique_ptr
对于绝大多数用例来说已经足够了,但也有一些例外,就像事件处理系统中的对象希望在析构函数中删除自身一样。观察原始指针是另一个例外。“如果你在跑步结束时没有看到泄漏记录的增加,那么泄漏就不会增加。”-你能进一步解释一下吗?如何在跑步结束时测量记录?数一数。如果有超过你可以快速计算的数量,那么它是否在增长并不重要。你的问题已经够多了。
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));
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();
    }