DeadCapacitor
DeadCapacitor

Reputation: 209

New Operator With Vectors

These questions are relatively straight forward. When using vectors, should I use the new operator when pushing back a new element? And which release method should I call? Here's what I mean:

// Release method: 1.
void ReleaseMethodOne( vector< int * > &ThisVector )
{
    // Clear out the vector.
    ThisVector.clear( );
    return;
}

// Release method: 2.
void ReleaseMethodTwo( vector< int * > &ThisVector )
{
    // Clear out the vector.
    for( unsigned uIndex( 0 ); uIndex < ThisVector.size( ); uIndex++ )
    {
        delete ThisVector.at( uIndex );
    }
    return;
}

int main( )
{
    vector< int * > Vector;

    // Add a new element.
    Vector.push_back( new int( 2 ) );

    // More code...

    // Free the elements before exiting. Which method should I call here?
    ReleaseMethodOne( Vector ); // This one?
    ReleaseMethodTwo( Vector ); // Or this one?

    return 0;
}

I've started learning vectors not long ago and the book I was learning from said that the vector's clear( ) method called each of the elements destructor. Do this apply to the new operator?

Upvotes: 4

Views: 6097

Answers (6)

npcomplete
npcomplete

Reputation: 174

As answered by others, vector does call the destructor of each element. In your case, the elements are pointers and hence it will not free the memory. For your application, the best choice is to use a reference counting smart pointer like boost:shared_ptr. Once there are no more references pointing to the elements (like the example you had written), the memory will be freed automagically.

PS: Do not use a "non-reference counting" smart pointer like std::auto_ptr with vector.

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361612

You should use ReleaseMethodTwo(), because if you've allocated the memory, then it's your responsibility to delete it.

std::vector::clear() only erases the elements from the vector. It doesn't call delete on the elements being erased!

Upvotes: 2

Elalfer
Elalfer

Reputation: 5338

if you are using vactor<int *> than you'll have a vector of pointers and you have to allocate memory for each elements and free this memory yourself also. It doesn't make much sense to use vector of pointers unless the size of type you want to store in the vector is quite big.

Actually when you do vector<T>::push_back(val) is it going to store a copy of val using a copy constructor T::T(T &orig) and call destructor for all elements when you do clear()

Upvotes: 0

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84189

STL containers store copies of the objects you give to them, pointers in your example. They never release any memory you explicitly allocated. You have to deallocate that memory yourself, so the second "release" method should be used.

Of course, you don't need to new every int. Just use vector<int> instead - you won't have to deal with manual memory management at all.

Upvotes: 5

Rob Kennedy
Rob Kennedy

Reputation: 163317

The clear method will indeed call destructors. However, your vector is storing pointers, and the destructor for pointers is a trivial no-op. It does not call delete.

Therefore, simply calling clear will not free the memory for all the int objects you allocated with new. You need to delete them.

If you use a smart pointer instead of an ordinary pointer, then the pointed-at objects will get freed at the appropriate time without you having to do anything special.

Upvotes: 5

James
James

Reputation: 5425

For what you are doing there you would need to use ReleaseMethodTwo. What it means by saying that it calls the element's destructor is that contained classes (not contained pointers) will lose scope and have their destructors called.

No STL container will ever call delete for you, so far as I know. If you allocate and pass in a pointer, you will need to deallocate.

Upvotes: 2

Related Questions