2017-08-02 46 views
2

我已经阅读了关于同一主题的多个类似问题,但我无法通过关注它们来解决问题。将指针存储到向量中时发生内存泄露

我想存储指向矢量,但我看到内存泄漏。我的代码如下。

#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; 
} 

Valgrind报告:“仍然可达:72,704字节在1块”。如果我不使用unique_ptr,并且只使用bv.emplace_back(new Derived);delete显式指定向量,则会出现同样的问题。什么导致了泄漏?

+0

这些字节可能来自'bv'向量本身。尝试将其移至'main'以确保其内容被删除。 – dasblinkenlight

+2

仍然可以访问的内存不是内存泄漏 – Justin

+1

@dasblinkenlight,72K?不太可能。 – SergeyA

回答

5

看起来像你实际存储基类的实例。 Derived()在堆栈上创建一个对象,然后make_unique将它传递给Base的构造函数。这是对象切片。 这不会解释泄漏,但表示代码可能不会做你期望的。

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

我同意@ cmaster的评论如下。 Valgrind确实跟踪malloc/free。经过一番研究后,我在stackoverflow上发现了另一个问题,它解释了观察结果。

包括的iostream

“作为C许多实现++标准库使用自己的内存池分配器。”他们只是不释放自己的记忆。

更多详细信息:Valgrind: Memory still reachable with trivial program using <iostream>

+0

我想存储基类的实例。在我真正的应用程序中,派生类是模板化的,因为我需要稍后访问它(当我不知道模板时),我将一个非模板指针存储到基类中。 – Sayan

+1

@Sayan我的评论是基于你的例子。很难看出你为什么想要在代码中进行对象切片。 – Sergei

+0

是的,我同意你的意见。 – Sayan