I'm currently getting myself into c++ for lower level coding with opengl. 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
.
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.
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.
But when I add a delete object
after the push_back
call the deconstructor of the WavefrontObject3D object
is called. This gives me a hint that the ptr_vector
isn't retaining the object
variable. 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?
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.
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.
Additional question: No, if you store the ptr_vector
by value its lifetime is managed by the scope of the surrounding class.
Let's write a simple implementation of 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. 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
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.
http://www.boost.org/doc/libs/1_50_0/libs/ptr_container/doc/reference.html#class-heap-clone-allocator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With