【问题标题】:Is there a MSVC 2013 std::list memory leak?是否存在 MSVC 2013 std::list 内存泄漏?
【发布时间】:2014-04-12 20:42:50
【问题描述】:

https://ideone.com/dA1Km2

这是一个简单示例程序的链接。它定义了一个自定义分配器,用于计算分配和释放之间的差异。

它创建然后销毁一个空的std::list

当它使用 gcc 或 clang 构建时(如链接中所示),它输出 0。这是意料之中的 - 解除分配的数量应该与分配的数量相同。

但是 MSVC 2013 输出 2。这个空的 std::list 进行了两次分配,以后不会被释放。

这是内存泄漏吗?如果没有,那里会发生什么,有没有办法真正清除 msvc 中的 std::list 特定内存?

【问题讨论】:

  • MSVC++ 有一个很好的调试器,你没有花足够的时间使用它。只需在 allocate() 和 deallocate() 函数上设置断点即可显示您的错误。
  • 我必须承认我真的没有看到它:) 什么是错误?
  • 显然我的自定义删除运算符没有调用析构函数。我还是不明白为什么。
  • 宾果游戏。相当糟糕,不是吗?
  • 是的。我期望重载 delete 运算符会调用析构函数(因为重载 new 会调用构造函数)。显然我是不正确的。

标签: visual-c++ memory-leaks allocator


【解决方案1】:

泄漏在您自己的代码中:您的custom_delete 未能调用std::list 对象的析构函数——它直接调用operator delete 以释放内存而不调用析构函数。

如果您修复程序以正确销毁列表,您将观察到没有泄漏(程序打印 0):

auto x = custom_new custom_list<int>;
x->~list(); // Destroy the list
custom_delete(x);
std::cout << the_manager.allocations << std::endl;

那么,为什么您只看到 Visual C++ std::list 实现的泄漏? Visual C++ 实现总是为空列表对象分配一个标记节点,以确保在移动列表时(或交换两个列表时),结束迭代器不会失效。您与 gcc 和 clang 一起使用的标准库实现显然不这样做。

【讨论】:

  • 是的。显然我不知道如何重载删除运算符:)
猜你喜欢
  • 1970-01-01
  • 2011-03-26
  • 2012-12-14
  • 2011-01-29
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
相关资源
最近更新 更多