【问题标题】:Why valgrind shows leaks, even when the vector containing dynamically allocated objects is freed?为什么 valgrind 显示泄漏,即使包含动态分配的对象的向量被释放?
【发布时间】:2014-07-04 12:03:44
【问题描述】:

我已经使用 new 在堆上分配了一个向量:

std::vector<t*> *vec = new std::vector<t*>;

此向量包含类对象,属于“t”类,这些类对象是使用 new 创建的

t *ptr1 = new t();
t *ptr2 = new t();
t *ptr3 = new t();
t *ptr4 = new t();

现在,当我删除向量时,预计添加到其中的所有这些对象也应该被销毁,我的意思是:

std::vector<t*> *vec = new std::vector<t*>;
 vec->push_back(ptr1);
 vec->push_back(ptr2);
 vec->push_back(ptr3);
 vec->push_back(ptr4);

ptr1、ptr2、ptr3、ptr4 指向的内存也应该被释放。

但 Valgrind 将此显示为泄漏! Valgrind 有问题吗?

==15634==
==15634== HEAP SUMMARY:
==15634==     in use at exit: 48 bytes in 8 blocks
==15634==   total heap usage: 12 allocs, 4 frees, 128 bytes allocated
==15634==
==15634== LEAK SUMMARY:
==15634==    definitely lost: 32 bytes in 4 blocks
==15634==    indirectly lost: 16 bytes in 4 blocks
==15634==      possibly lost: 0 bytes in 0 blocks
==15634==    still reachable: 0 bytes in 0 blocks
==15634==         suppressed: 0 bytes in 0 blocks
==15634== Rerun with --leak-check=full to see details of leaked memory
==15634==
==15634== For counts of detected and suppressed errors, rerun with: -v
==15634== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

以下是完整程序,供大家参考:

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

class t
{
int *ptr;
public:
  t()
  {
    cout << "t's constructor" << endl;
    ptr = new int(50);
  }
 ~t()
  {
    cout << "t's destructor called" << endl;
    delete ptr;
  }

  void func()
  {
     cout << "This is class t's function" << endl;
  }

};

//void func(int *ptr, t* ptr1)
void func(t* ptr1)
{
 //delete ptr;
 delete ptr1;
}

int main( )
{
 //int *ptr;

 t *ptr1 = new t();
 t *ptr2 = new t();
 t *ptr3 = new t();
 t *ptr4 = new t();
 //ptr =new int(20);
 //func(ptr, ptr1);
 //func(ptr1);

 std::vector<t*> *vec = new std::vector<t*>;
 vec->push_back(ptr1);
 vec->push_back(ptr2);
 vec->push_back(ptr3);
 vec->push_back(ptr4);

 delete vec;
 //delete ptr1; ===============> Are these required? Shouldn't delete vec take care?
// delete ptr2;
 //delete ptr3;
 //delete ptr4;

}

【问题讨论】:

  • C++ 不是 java,尽可能避免使用new,该语言允许您使用没有动态分配的类型。

标签: c++ linux vector valgrind


【解决方案1】:

现在,当我删除向量时,预计添加到其中的所有这些对象也应该被销毁

它们是。你添加了指针,指针将被销毁。

不过,这并没有说明指针指向的东西。总之,你的假设是错误的。

您的选择:

  • delete 销毁向量之前的每个指针
  • 使用智能指针
  • 停止使用指针!停止使用动态分配!
    std::vector&lt;t&gt; 在大多数情况下应该没问题。

【讨论】:

  • @Ely 也许您不应该传递向量。也许你应该传递一个const 引用。
  • @Ely 返回在子函数中创建的向量并不昂贵,因为移动语义和返回值优化。
  • @Ely:“我总是喜欢在我的向量中使用指针。” 很抱歉,这听起来很粗鲁,但这是非常糟糕的做法,而且听起来缺乏经验。您应该更喜欢按值传递,并且可以使其非常有效。在容器中存储指针会造成一团糟,根本不值得。
  • 我喜欢 std::move 它 std::move 它。我喜欢 std::move 它 std::move 它。
  • 不幸的是,有些对象反对(抱歉)被移动。
【解决方案2】:

当verctor被销毁时,它只销毁了vector分配的内存。这意味着,verctor 需要内部结构来保留您插入的 t*。该内存肯定会被desctor析构函数删除。但是你“新”的值并没有被向量释放。

你是删除这些记忆的责任人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多