ptr_vector如何管理内存?

时间:2012-07-26 09:13:03

标签: c++ memory-management boost

我目前正在使用opengl进行低级编码的c ++。我来自一个沉重的objc背景,所以我对内存管理有一些了解,但我似乎无法理解“boost”库如何管理像ptr_vector这样的容器类型。

我认为我的问题与我不知道ptr_vector如何管理自身及其对象的破坏这一事实有关。

请查看以下代码:

// Header file
...
ptr_vector<IObject3D> objects;
...

// Implementation file
...
void ApplicationEngine::init()
{
    WavefrontObject3D *object = new WavefrontObject3D("Ninja.obj");
    objects.push_back(object); 
}
...

所以,对于实际问题:我是否通过“对象”变量在这里创建泄漏?

我习惯使用objc中的显式调用手动保留和释放我的对象: 之前我不得不alloc init使用WavefrontObject3D object,将其添加到数组中,然后release使用相同的对象以避免泄漏。

但是当我在delete object调用后添加push_back时,会调用WavefrontObject3D object的解构函数。这给了我一个提示,ptr_vector没有保留object变量。我的假设是否正确?

其他但相关的问题:让我们说要销毁包含的类ApplicationEngine我不需要在ptr_vector上调用某种解构函数或者它管理的元素?

4 个答案:

答案 0 :(得分:6)

不,这不会造成泄漏。当容器超出范围时,所有ptr_*容器都将删除存储在其中的对象。

如果在将对象添加到容器后删除该对象,则会创建undefined behavior,因为容器将尝试再次将其删除。

其他问题:不,如果按值存储ptr_vector,则其生命周期由周围类的范围管理。

让我们写一个ptr_vector的简单实现。它不支持间接迭代器和自定义删除器以及许多其他东西,但显示了使用的原则。

template <typename T>
class ptr_vector {
public:
  // assume control over it
  void push_back(T* x) 
  { if(x) c_.push_back(x); else throw bad_pointer(); }

  ~ptr_vector() { 
    // delete everything that is stored here
    for(auto x : c_)  delete x;
  }
private:
  std::vector<T*> c_;
};


// a user class
struct user_class {
  void addSomething() { x.push_back(new int(23)); }
  ptr_vector<int> x;
};

如果用户类超出范围,ptr_vector的析构函数将会 被叫,所有记忆都将被收回。看不到泄漏。

答案 1 :(得分:2)

void push_back( T* x );
  

要求:x!= 0效果:将指针插入容器中   取得它的所有权抛出:bad_pointer如果x == 0异常安全:   强有力的保证

template
    < 
        class T, 
        class CloneAllocator = heap_clone_allocator,
        class Allocator      = std::allocator<void*>
    >
    class ptr_vector : public ptr_sequence_adapter
                              <
                                  T,
                                  std::vector<void*,Allocator>,
                                  CloneAllocator
                              >

因此,您可以指定自己的CloneAllocator而不删除存储在ptr_vector中的元素,但heap_clone_allocatorCloneAllocator的默认参数)会删除析构函数中的所有存储元素。

http://www.boost.org/doc/libs/1_50_0/libs/ptr_container/doc/reference.html#class-heap-clone-allocator

答案 2 :(得分:0)

ptr_vector将释放其析构函数中的所有元素,因此您不必执行任何操作,也就是创建对象,将它们添加到ptr_vector,让管理层离开它。显式调用delete会使对象被销毁两次(一次是在你请求时,一次是在ptr_vector完成时)。换句话说,ptr_vector不会复制对象。

ApplicationEngine完成时,如果它有ptr_vector的实例,则会调用该向量的析构函数,然后删除添加的对象。

答案 3 :(得分:0)

ptr_containers own the memory pointed at by the pointer you pass to it. 有关可克隆概念的更多信息,请阅读the docs