如何释放指针向量?

时间:2010-09-14 18:00:59

标签: c++ object vector erase delete-operator

如何在指针向量中释放内存? 这是代码:

class A
{
    private:
        int x,y,z;
    public:
        A(param1, param2, param3)
        {
            x=param1;
            y=param2;
            z=param3;
        }
        ~A()
        {
            //prompts an alertbox, warning me about the successful call of the destructor;
        }
};

...
vector<A*> list;
list.push_back(new A(1,2,3));

list.erase(list.begin()+index);//SHOULD delete the object from the memory;
list.clear();

我发现.erase()没有释放内存,也没有调用析构函数;我尝试在每个列表条目上使用delete进行迭代,但在一次迭代后崩溃。已经检查列表条目是否已经为NULL,以避免任何错误。 我错过了什么吗? 另外,我必须只使用STL,不需要Boost。

6 个答案:

答案 0 :(得分:8)

list.erase将为其成员元素释放内存(并调用它们的析构函数,如果存在的话);它不会在它们上面调用delete

提升shared_ptr将是明显的做法。如果您不想使用它,那么您要么编写自己的智能指针类,要么遍历list并在每个指针上调用delete,然后再调用erase。你可以用以下的方式做到这一点:

void my_delete(A *p)
{
    delete p;
}

...

std::for_each(list.begin(), list.end(), my_delete);

答案 1 :(得分:4)

for( std::vector<A*>::iterator i = list.begin(), endI = list.end(); i != endI; ++i)
{
   delete *i;
}
list.clear();

或者,使用新的lambda函数

std::for_each( list.begin(), list.end(), []( A* element) { delete element; });
list.clear();

答案 2 :(得分:3)

erase只会删除向量(指针)中的内容,而不会对它们可能指向的内容做任何事情。

如果您想要删除的内容,您需要自己处理。

我的建议是避免自己处理任何,并考虑改用Boost ptr_vector

答案 3 :(得分:2)

销毁后,STL容器将销毁它包含的对象。如果这些对象是指针,那么它将破坏指针。对于裸体,哑指针, 这不会删除它们指向的对象 。这就是为什么通常最好使用智能指针。智能指针将删除它们在删除时引用的对象; std::shared_ptr跟踪复制指针以及对给定对象的引用数量,并且仅在最后一个指针死亡时删除该对象。在寻找适合的智能指针时,这总是一个很好的第一候选人。然后,您的容器将按如下方式声明:std::vector< std::shared_ptr<A> >

但是,你的编译器/ std lib可能没有std::shared_ptr,这是下一个C ++标准的一个特性,通常是明年的预期。但是,它可能带有std::tr1::shared_ptr,这是2003年的TR1功能。(如果其他所有功能都失败,则提升为boost_shared_ptr,但您已经排除了提升。)

可以手动管理STL容器中动态分配的对象,但这是一种负担,容易出错。例如,您必须通过return语句或异常阻止函数提前返回(在手动清理之前),并且必须注意容器上的复制操作。 (否则两个容器会有指向相同对象的指针,然后你可能会尝试销毁两次。)
手动管理资源是一种PITA,容易出错,最好避免。

答案 4 :(得分:1)

您发布的代码不是合法的C ++。此外,擦除不会删除已分配的对象,它只会擦除向量的内容,在您的情况下是指针。您分配的实际对象未被删除。这是一个正确的方式来做你想要的:

#include <vector>
#include <algorithm>

class A
{
    int x,y,z;

public:
    A (int param1, int param2, int param3) :
        x (param1), y (param2), z (param3)
    {
    }
};

struct Deleter
{
    template <typename T>
    void operator () (T *obj) const
    {
        delete obj;
    }
};

int
main ()
{
    std::vector<A*> list;

    list.push_back (new A (1, 2, 3));
    list.push_back (new A (4, 5, 6));
    list.push_back (new A (7, 8, 9));

    std::for_each (list.begin (), list.end (), Deleter ());
    list.clear ();
}

您还可以查看Boost Ptr Container库,以安全且可重复使用的方式解决此问题。在C ++ 0x中,有一个std :: unique_ptr模板类,它支持可移动的语义,可以与STL容器和算法一起使用来自动清理内存。

答案 5 :(得分:0)

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

list.clear();

如果您制作类似的内容并且您的代码崩溃,请发布确切的代码和崩溃信息。