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

Has*_*ing 19 c++ pointers memory-leaks memory-management vector

我有一个向量,我填充指向对象的指针.我正在努力学习良好的记忆管理,并提出一些一般性问题:

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

Dav*_*nco 23

  1. 使用模板内存分配器实现向量,这些分配器为您处理内存管理,因此它们有点特殊.但作为一般经验法则,您不必调用delete未使用new关键字声明的变量,因为堆栈和堆分配之间存在差异.如果在堆上分配了东西,则必须删除它(释放)以防止内存泄漏.
  2. 不.delete myVec[index]当您迭代所有元素时,您必须明确地调用.

例如:

for(int i = 0; i < myVec.size(); ++i)
   delete myVec[i];
Run Code Online (Sandbox Code Playgroud)

话虽如此,如果您计划在向量中存储指针,我强烈建议使用boost::ptr_vector哪个自动处理删除.


fre*_*low 11

当我完成向量时,我必须遍历它并在每个指针上调用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>());
}
Run Code Online (Sandbox Code Playgroud)

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

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

std::for_each(vec.begin(), vec.end(), boost::lambda::delete_ptr());
Run Code Online (Sandbox Code Playgroud)

或者你可以编写自己的仿函数:

struct delete_ptr
{
    template <class T>
    void operator()(T* p)
    {
        delete p;
    }
};

std::for_each(vec.begin(), vec.end(), delete_ptr());
Run Code Online (Sandbox Code Playgroud)