5

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

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。

4

6 回答 6

8

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

Boostshared_ptr将是这样做的明显方式。如果您不想使用它,您要么编写自己的智能指针类,要么在list调用. 您可以通过以下方式巧妙地做到这一点:deleteerase

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

...

std::for_each(list.begin(), list.end(), my_delete);
于 2010-09-14T18:06:01.140 回答
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();
于 2010-09-14T18:07:28.903 回答
3

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

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

我的建议是避免自己处理任何这些,并考虑使用Boostptr_vector

于 2010-09-14T18:08:25.317 回答
2

在销毁时,STL 容器将销毁它包含的对象。如果这些对象是指针,那么它将破坏指针。对于裸指针,这不会删除它们指向的对象。这就是为什么通常最好为此使用智能指针。智能指针将在删除时删除它们引用的对象;std::shared_ptr跟踪复制指针以及存在多少对给定对象的引用,并且仅在最后一个指针死亡时删除该对象。在寻找合适的智能指针时,这始终是一个很好的首选。然后您的容器将像这样声明:std::vector< std::shared_ptr<A> >

但是,您的编译器/标准库可能不附带std::shared_ptr,这是下一个 C++ 标准的一个特性,通常预计在明年。但是,它可能会附带std::tr1::shared_ptr,这是 2003 年的 TR1 功能。(如果所有其他方法都失败了,boost 有boost_shared_ptr,但您已经排除了 boost。)

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

于 2010-09-14T18:08:38.733 回答
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 容器和算法一起使用以自动清理内存。

于 2010-09-14T18:11:19.250 回答
0
for(size_t i = 0; i < list.size(); ++i)
{
    删除列表[i];
}

list.clear();

如果你做了这样的事情并且你的代码崩溃了,请发布确切的代码和崩溃信息。

于 2010-09-14T18:05:38.893 回答