【问题标题】:vector of unique_ptr not being fully deleted (memory leaks) [duplicate]unique_ptr 的向量没有被完全删除(内存泄漏)[重复]
【发布时间】:2015-04-30 14:29:33
【问题描述】:

我正在编写一个程序,最终需要我为自定义类的对象创建一个 unique_ptrs 向量。我遇到了一些内存泄漏,所以我决定从等式中删除自定义类,并使用 unique_ptr 进行尝试。

当我尝试在堆栈上创建 unique_ptr 时,没有泄漏。但是,创建 unique_ptrs 的向量 确实 泄漏。为了好玩,我还尝试将 unique_ptr 移动到向量中,以查看发生了什么。我的代码如下(包括 MSVS 内存检查):

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

#include <vector>
#include <memory>
using namespace std;

int main()
{
    vector<unique_ptr<int>> testvector;
    unique_ptr<int> addMe;

    testvector.emplace_back(move(addMe));
    testvector.clear();

    _CrtDumpMemoryLeaks();
    return 0;
}

当我注释掉除“addMe”的创建之外的所有内容时,我没有泄漏。
当我注释掉除“testvector”的创建之外的所有内容时,我得到 8 个字节的内存泄漏。
当我将“addme”的 emplace_back 注释到“testvector”时,我得到 8 个字节的内存泄漏。
当我什么都不注释掉时,我得到 12 个字节的内存泄漏。
当我用“shared_ptr”替换所有“unique_ptr”时,一切都表现相同。

我做错了什么,还是智能指针向量会出现这种情况?

谢谢!

【问题讨论】:

  • 尝试将所有代码放在大括号中,以便在检查内存泄漏之前运行向量的析构函数。 clear() 将销毁对象,但向量可能会保留内存(您可以使用capacity() 检查)以供将来使用。
  • @Cornstalks 我应该把哪个代码放在大括号里?
  • _CrtDumpMemoryLeaks(); 之前的所有内容。这样,您可以确保testvector 在检查内存泄漏之前 被完全销毁。
  • 漂亮,谢谢!像魅力一样工作。

标签: c++ visual-studio c++11 vector unique-ptr


【解决方案1】:

std::vector::clear() 的文档中所述

http://www.cplusplus.com/reference/vector/vector/clear/

从向量中移除所有元素(被销毁),留下 大小为 0 的容器。 不保证会发生重新分配,也不保证向量容量会因为调用此函数而改变。一种 强制重新分配的典型替代方法是使用交换。

这意味着,元素被删除,但std::vector 使用的内部存储没有。

如果你的编译器支持C++11,那么你可以使用std::vector::shrink_to_fit()try使capacity设置为size,清除后等于0。

http://www.cplusplus.com/reference/vector/vector/shrink_to_fit/

Shrink to fit 请求容器减小其容量以适应其 大小。

请求是非绑定的,容器实现是免费的 否则优化并使向量具有更大的容量 比它的大小。

这可能会导致重新分配,但对向量大小没有影响 并且不能改变它的元素。

【讨论】:

  • 我认为您错过了shrink_to_fit() 的一小部分:它没有约束力"It is a non-binding request to reduce capacity() to size(). It depends on the implementation if the request is fulfilled." 即使在shrink_to_fit() 之后,向量也可能保留一些额外的内存。
  • 我添加了那行,但似乎并没有解决所有问题。内存泄漏从 12 个字节减少到 8 个字节。
  • 把你所有的东西放在一个单独的函数中,并在函数返回后调用_CrtDumpMemoryLeaks()。这段代码应该没有泄漏,只是你还在函数的框架中,还有没有被破坏的对象。
  • @Cornstalks,谢谢,已在答案中修复
  • 把它放在一个单独的函数中是有效的,即使没有收缩。我一定会记住缩小!
猜你喜欢
  • 2017-01-13
  • 2019-10-06
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-05
  • 1970-01-01
相关资源
最近更新 更多