在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?

Posted

技术标签:

【中文标题】在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?【英文标题】:What do I need to do before deleting elements in a vector of pointers to dynamically allocated objects?在删除指向动态分配对象的指针向量中的元素之前,我需要做什么? 【发布时间】:2011-05-02 23:09:02 【问题描述】:

我有一个向量,我用指向对象的指针填充。我正在努力学习良好的内存管理,并且有几个一般性问题:

    当我处理完向量后,是否必须循环遍历它并在每个指针上调用 delete? 为什么我不必在没有 new 语句的情况下对向量或我声明的任何其他变量调用 delete,但必须对指针调用 delete? 如果向量在返回的函数中声明(导致向量超出范围),C++ 是否会为我释放指针的内存?

【问题讨论】:

【参考方案1】:

作为 David Titarenco 提到的 boost::ptr_vector 的替代方案,您可以轻松修改 std::vector 以自动释放内存以包含删除指针:

template<class T>
class Group : public std::vector<T>

public:
    virtual ~Group() ;
;

template<class T>
class Group<T *> : public std::vector<T *>

public:
    virtual ~Group()
    
        std::vector<T *>::reverse_iterator it;
        for (it = this->rbegin(); it != this->rend(); ++it)
            delete *it;
    
;

std::vector 提供的所有功能都是继承的,因此您可以以相同的方式添加项目:

Group<Foo *> *bar = new Group<Foo *>();
bar->push_back(new Foo());
bar->push_back(new DerivedFoo());

// Deleting the Group will free all memory allocated by contained pointers
delete bar;

【讨论】:

【参考方案2】:

当我完成向量后,我是否必须循环遍历它并在每个指针上调用 delete 是真的吗?

好吧,你不必手动循环,你也可以使用算法:

#include <vector>
#include <algorithm>
#include <memory>

int main()

    std::vector<Base*> vec;
    vec.push_back(new Derived());
    vec.push_back(new Derived());
    vec.push_back(new Derived());

    // ...

    std::for_each(vec.begin(), vec.end(), std::default_delete<Base>());

如果你没有 C++0x 编译器,你可以使用 boost:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/construct.hpp>

std::for_each(vec.begin(), vec.end(), boost::lambda::delete_ptr());

或者您可以编写自己的函子:

struct delete_ptr

    template <class T>
    void operator()(T* p)
    
        delete p;
    
;

std::for_each(vec.begin(), vec.end(), delete_ptr());

【讨论】:

【参考方案3】:

您使用new 分配的所有内容稍后都必须分配给delete。您未使用 new 显式分配的对象不应该是 delete

如果您不想手动管理对象但希望向量“拥有”它们,那么按值存储对象而不是存储指向它们的指针可能会更好。所以你可以用std::vector&lt;SomeClass&gt;代替std::vector&lt;SomeClass*&gt;

【讨论】:

【参考方案4】:

如果您可以访问 C++0x,也可以使用 std::unique_ptr。它取代了不能在容器中使用的已弃用的 std::auto_ptr。

【讨论】:

【参考方案5】:
    是的 向量是使用模板内存分配器实现的,它为您处理内存管理,因此它们有些特殊。但作为一般经验法则,由于堆栈和堆分配之间的差异,您不必对未使用 new 关键字声明的变量调用 delete。如果在堆上分配了东西,则必须将其删除(释放)以防止内存泄漏。 没有。在遍历所有元素时,您必须明确调用 delete myVec[index]

例如:

for(int i = 0; i < myVec.size(); ++i)
   delete myVec[i];

话虽如此,如果您打算将指针存储在向量中,我强烈建议您使用boost::ptr_vector,它会自动处理删除。

【讨论】:

3:C++ 当然会释放指针使用的内存,因为它们是在堆栈上分配的。但是这些指针指向的对象很可能是在堆上分配的,因此需要被删除。当然,向量中的指针可以指向堆栈分配的对象,这些对象可能不会被删除。通常,您永远不应该将非常量指针存储到向量中,以堆栈分配的对象。

以上是关于在删除指向动态分配对象的指针向量中的元素之前,我需要做啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何从指向对象的指针向量中删除对象? [复制]

C ++在向量迭代中删除并返回指向对象的指针

堆中连续分配对象的动态向量

我是否正确删除了指向对象的向量?

我是不是正确删除了指向对象的指针向量?

如果已删除,如何从向量中删除对象