简体   繁体   English

ptr_vector如何管理内存?

[英]How does ptr_vector manage memory?

I'm currently getting myself into c++ for lower level coding with opengl. 我目前正在使用opengl进入c ++进行低级编码。 I come from a heavy objc background so I have some understanding about memory management but I can't seem to get how the "boost" library manages container types like ptr_vector . 我来自一个沉重的objc背景,所以我对内存管理有一些了解,但我似乎无法得到“boost”库如何管理像ptr_vector这样的容器类型。

I think my problem is related to the fact that I have no idea how ptr_vector manages the destruction of itself and its objects. 我认为我的问题与我不知道ptr_vector如何管理自身及其对象的破坏这一事实有关。

Please take a look at the following code: 请看下面的代码:

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

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

So, for the actually question : am I creating a leak here through the "object" variable? 所以,对于实际问题 :我是否通过“对象”变量在这里创建泄漏?

I'm used to retain and release my objects manually with explicit calls in objc: previously I had to alloc init the WavefrontObject3D object , add it to an array and afterwards release that same object to avoid leaks. 我习惯于在objc中使用显式调用手动保留和释放我的对象:之前我必须为alloc init分配一个WavefrontObject3D object ,将它添加到一个数组中,然后release相同的对象以避免泄漏。

But when I add a delete object after the push_back call the deconstructor of the WavefrontObject3D object is called. 但是当我在push_back调用之后添加一个delete object ,会调用WavefrontObject3D object的解构object This gives me a hint that the ptr_vector isn't retaining the object variable. 这给了我一个提示,即ptr_vector没有保留object变量。 Is my assumption correct? 我的假设是否正确?

Additional, but related, question: let's say I want to destroy the containing class ApplicationEngine don't I have to call some kind of deconstructor on the ptr_vector or the elements it manages? 另外但相关的问题:假设我要销毁包含类的ApplicationEngine我不是要在ptr_vector或它管理的元素上调用某种解构ptr_vector吗?

No, this doesn't create a leak. 不,这不会造成泄漏。 All ptr_* containers will delete objects that are stored in them when the container goes out of scope. 当容器超出范围时,所有ptr_*容器都将删除存储在其中的对象。

If you delete the object after adding it to the container, you will create undefined behavior as the container will attempt to delete it again. 如果在将对象添加到容器后删除该对象,则会创建undefined behavior因为容器将尝试再次将其删除。

Additional question: No, if you store the ptr_vector by value its lifetime is managed by the scope of the surrounding class. 附加问题:不,如果按值存储ptr_vector ,其生命周期由周围类的范围管理。

Let's write a simple implementation of ptr_vector . 让我们写一个ptr_vector的简单实现。 It has no support for indirect iterators and custom deleters and a lot of other things but shows the principles used. 它不支持间接迭代器和自定义删除器以及许多其他东西,但显示了使用的原则。

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;
};

If user class goes out of scope, the destructor of ptr_vector will be called and all memory will be reclaimed. 如果用户类超出范围,将调用ptr_vector的析构函数并回收所有内存。 No leak in sight. 看不到泄漏。

void push_back( T* x );

Requirements: x != 0 Effects: Inserts the pointer into container and takes ownership of it Throws: bad_pointer if x == 0 Exception safety: Strong guarantee 要求: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
                              >

So you can specify your own CloneAllocator and not delete elements that stored in ptr_vector, but heap_clone_allocator (default par for CloneAllocator ) deletes all stored elements in destructor. 所以,你可以指定自己的CloneAllocator并不会删除存储在ptr_vector元素,但heap_clone_allocator (默认面值CloneAllocator )删除析构函数中存储的所有元素。

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

ptr_vector will free all the elements in its destructor, so you don't have to do anything more than what you already do, that is, create the objects, add them to the ptr_vector , and leave the management to it. ptr_vector将释放其析构函数中的所有元素,因此您不必执行任何操作,也就是创建对象,将它们添加到ptr_vector ,并将管理保留给它。 Calling delete explicitly will make the object destroyed twice (once when you request it and again when the ptr_vector finishes). 显式调用delete将使对象被销毁两次(一次是在你请求时,一次是在ptr_vector完成时)。 In other words, ptr_vector does not duplicate the object. 换句话说, ptr_vector不会复制该对象。

When the ApplicationEngine finishes, if it has an instance of the ptr_vector , the destructor of that vector will be called, that in turn deletes the added objects. ApplicationEngine完成时,如果它具有ptr_vector的实例,则将调用该向量的析构函数,然后删除添加的对象。

ptr_containers own the memory pointed at by the pointer you pass to it. ptr_containers 拥有传递给它的指针所指向的内存。 Read the docs for more info on cloneable concepts. 阅读文档以获取有关可克隆概念的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM