C++ 将指针存储到向量时内存泄漏

C++ 将指针存储到向量时内存泄漏,c++,vector,valgrind,smart-pointers,unique-ptr,C++,Vector,Valgrind,Smart Pointers,Unique Ptr,我已经阅读了关于同一主题的多个类似问题,但我无法通过遵循这些问题来解决我的问题 我想将指针存储在向量中,但我发现内存泄漏。我的代码如下 #include <iostream> #include <vector> #include <memory> class Base { public: virtual ~Base() {} }; class Derived : public Base {}; std::vector<std

我已经阅读了关于同一主题的多个类似问题,但我无法通过遵循这些问题来解决我的问题

我想将指针存储在向量中,但我发现内存泄漏。我的代码如下

#include <iostream>
#include <vector>
#include <memory>

class Base 
{
    public:
       virtual ~Base() {}
};

class Derived : public Base {};

std::vector<std::unique_ptr<Base>> bv;

int main()
{
    for (int i = 0; i < 10; i++)
       bv.emplace_back(std::make_unique<Base>(Derived()));

    bv.clear();

    return 0;
}
#包括
#包括
#包括
阶级基础
{
公众:
虚拟~Base(){}
};
派生类:公共基{};
std::载体bv;
int main()
{
对于(int i=0;i<10;i++)
emplace_back(std::make_unique(派生());
bv.clear();
返回0;
}

Valgrind报告:“仍然可以访问:1个块中有72704个字节”。如果我不使用
unique\u ptr
,而只使用
bv.emplace\u back(新派生),我也会遇到同样的问题
从向量中显式删除
指针。导致泄漏的原因是什么?

看起来您实际上存储了基类的实例。派生()在堆栈上创建一个对象,然后使其唯一并将其传递给Base的构造函数。这是对象切片。 这不会解释泄漏,但表明代码可能没有达到预期效果

补充: DELETED:free()并不总是将内存返回系统。Libc将为将来的malloc()保留此内存。这可能解释了你的观察

我同意@cmaster下面的评论。Valgrind确实跟踪malloc/free。经过一点研究,我发现了另一个关于stackoverflow的问题,这解释了观察结果

包括iostream

“C++标准库的许多实现使用它们自己的内存池分配器”,它们只是不释放它们的内存。
更多详细信息:

这些字节可能来自
bv
vector本身。尝试将其移动到
main
以确保其内容已被删除。仍然可访问的内存不是内存leak@dasblinkenlight72K?不太可能。@SergeyA只有一个块,还能是什么?我无法在我的机器上重现这个问题(Debian 9,
g++
)。必须是一些特定于实现的问题。72k看起来相当大,它的大小肯定与您显示的代码无关。我想存储基类的实例。在我的实际应用程序中,派生类是模板化的,因为我以后需要访问它(当我不知道模板时),所以我存储了一个指向基类的非模板指针。@Sayan我的评论基于您的示例。很难理解为什么要在代码中进行对象切片。是的,我同意你的看法。
free()
可能不会将内存返回到系统,但
valgrind
会跟踪从
malloc()
返回的内容以及传递到
free()
的内容。毕竟,valgrind实际上是在模拟CPU上运行程序的,它不仅仅像strace那样监听系统调用。因此,实施细节肯定不是这个问题的答案。