向量释放问题与数组相比

时间:2010-08-20 11:39:50

标签: c++

我将动态分配的类指针存储在如下的向量中。

     vector<Test *> v;
    Test *t1 = new Test;
    Test *t2 = new Test;
    v.push_back(t1);
    v.push_back(t2);

现在,如果我必须释放Test对象,我必须循环遍历整个向量并逐个释放,然后清除。

for(int i = 0; i<v.size(); i++)
     {
         delete v[i];
     }
     v.clear();

向量中是否有任何函数可以释放所有内部对象。该函数应该为每个对象调用Test类析构函数。 我知道Vector类很难指针是本地对象的地址还是动态分配的。 但是,只要开发人员确信所有动态分配,他就可以使用释放功能(如果提供的话)。

虽然vector被视为高级数组,但释放数组中的对象比下面容易得多。

Test  *a = new Test[2];
delete []a;

向量中是否有任何函数可以释放所有内部对象?

5 个答案:

答案 0 :(得分:4)

你的例子完全没有做同样的事情。

如果你想要这个数组代码的向量等价物:

Test  *a = new Test[2];
delete []a;

只是

std::vector<Test> a(2);

如果你有一个指向动态分配对象的指针向量,你需要删除它们中的每一个,如你的例子所示:

for(int i = 0; i<v.size(); i++)
 {
     delete v[i];
 }

但是对于数组来说同样如此:

Test *t1 = new Test;
Test *t2 = new Test;
Test **a = new Test*[2];
a[0] = t1;
a[1] = t2;
必须使用这样的循环删除

for(int i = 0; i<2; i++)
 {
     delete a[i];
 }
delete[] a;

在第一种情况下,您有两个对象存储在某种容器中。该容器可以是矢量,也可以是数组。

在这两种情况下,由于对象直接存储在容器中,因此在销毁容器时会调用它们的析构函数。您不需要做任何事情来销毁或删除单个成员,您只需要销毁容器(使用堆栈分配的向量更简单,您甚至不需要调用delete[]

但是如果你的容器存储指向动态分配对象的指针,那么你有责任在某些时候删除这些对象。无论您的容器是数组还是向量,都是如此。

答案 1 :(得分:2)

不,无法请求std::vector个完整的指针自动在其所有元素上调用delete

但是,有其他第三方容器可以通过在从向量中删除指针时自动删除指针,或者当向量析出时使这种事情更容易。例如,boost::ptr_vector and friends

答案 2 :(得分:2)

简短的回答是否定的。 C ++没有提供指针释放函数的向量。

答案很长很多:

  1. 使用智能指针,忘记free'ing(c ++ 0x中有shared_ptrunique_ptr可满足您的大部分需求。或者,使用像Tyler建议的Boost ptr_vector。

  2. 为容器中的每个项目delete写一个简单的通用算法并不困难(使用带迭代器的模板)。

  3. (警告:未经测试的代码,没时间检查)

    template<class It>
    void delete_clear_ptr_cont( const It &beginIt, const It &endIt )
    {
        for( auto it = beginIt; it != endIt; ++it )
        {
            delete it;
        }
        erase( beginIt, endIt );
    }
    

答案 3 :(得分:1)

不,vector不知道它可以用指针实例化。即使它是,有些情况下你没有拥有指针,你不想要删除行为。

在大多数情况下,我们只使用智能指针向量,例如shared_ptr。但是,有时候shared_ptr不合适。对于这些情况,我们的工具箱中有一个仿函数,如下所示:

#include <functional>

template<typename T>
struct PointerDelete : public std::unary_function<T*, T*>
{
   T* operator()(T*& p) const
   {
      delete p;
      return 0;
   }
};

然后,假设你有一个vector<Foo*>,你可以这样做:

#include <algorithm>

std::for_each(v.begin(), v.end(), PointerDelete<Foo>());
// or
std::transform(v.begin(), v.end(), v.begin(), PointerDelete<Foo>());

如果你可以使用boost库,还有ptr_containers,它们是拥有指针的容器,并在容器销毁时自动执行删除。

答案 4 :(得分:0)

之前我问了同样的问题,我被建议使用Boost库,你会发现很棒的提示 here或者只是你可以理解智能指针如下:

而不是有一个指针向量,你将有一个智能指针的向量,就像每个新的你将使它自己删除而不必担心。