【问题标题】:C++ Memory Leak Using STL Containers使用 STL 容器的 C++ 内存泄漏
【发布时间】:2015-01-15 23:25:06
【问题描述】:

以下代码给了我内存泄漏(使用 Visual Studio):

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <vector>
#include <memory>

struct Listener {};

struct Subject
{
    std::vector<Listener*> listeners;
};

int main(void)
{
    Subject subject;
    _CrtDumpMemoryLeaks();
    return 1;
}

我认为这是因为当 Subject 类被实例化时,STL 向量容器正在使用堆上的内存。如何确保程序退出时向量容器被销毁? (我已经尝试删除 Subject 析构函数中的容器,但这似乎不起作用)。

【问题讨论】:

  • -1 到 MS 用于将此函数命名为 DumpMemoryLeaks 而不是 ReportAllocatedMemory
  • _CrtDumpMemoryLeaks 通过统计新闻并确保它们都匹配来检测泄漏。因为subject 永远不会超出范围,我猜它被视为优秀的参考。试试int main(void) {{Subject subject;}_CrtDumpMemoryLeaks(); return 1}

标签: c++ memory-leaks stl


【解决方案1】:

确保Listener 析构函数销毁它需要的所有东西。 STL 容器所做的只是调用它所持有的对象的析构函数。处理类本身的内存仍然是您的责任。

更具体地说,在类中使用newmalloc 声明的任何内容都必须由析构函数释放。 STL 容器不知道如何删除它。

【讨论】:

  • 这不会释放任何已分配的Listener 对象。 Subject 需要一个析构函数来释放它们。
【解决方案2】:

std::vector&lt;Listener*&gt; listeners; 不会释放 Listeners 的成员。您必须使用以下方法删除向量内的每个侦听器:

for (int i = 0; i < listeners.size(); i++) delete listeners[i]

就我个人而言,我通过使用智能指针来避免此类问题:

std::vector<std::unique_ptr<Listener>> listeners

_CrtDumpMemoryLeaks 通过计算新闻并确保它们都匹配来检测泄漏。因为主题永远不会超出范围,我猜它被视为优秀的参考。试试int main(void) {{Subject subject;}_CrtDumpMemoryLeaks(); return 1}

【讨论】:

  • 好的一般建议;但它没有解释为什么发布的代码(不创建任何侦听器)报告泄漏。
  • 好建议。我实际上尝试过,并理解为什么要使用唯一指针,只是无法弄清楚为什么它仍然显示分配的内存。正如您在评论中指出的那样,我需要用大括号括起来以确保调用析构函数。
【解决方案3】:

vector在程序退出时被销毁,你不需要确保它。你确实需要确保_CrtDumpMemoryLeaks在销毁后被调用,如果你不希望它报告分配的内存为“泄漏”:

int main()
{
    { Subject subject; }
    _CrtDumpMemoryLeaks();
    return 1;
}

【讨论】:

  • 是的。这似乎有效。使用_CrtDumpMemoryLeaks 时,是否应该始终将代码括在花括号中? (第一次使用)。
  • @JamesB 问题是它不报告“内存泄漏”,它报告分配的内存。如果您希望分配的内存表示泄漏,则需要确保在所有析构函数都运行后调用它。
  • 您也可以在 main 函数的开头调用 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
相关资源
最近更新 更多