views:

113

answers:

4

Hi,

If I have a vector<string*> *vect or a map<pair<string*, int*>, string*> *map,
how to clean up everything (including all object the vector/map contains)?
(Everything (vector, map, contents, string, ints) is allocated with new)

Is

delete vect;
delete map;

enough?

+5  A: 

No, you must iterate through the vector / map, remove and delete its items one by one (which, as @SB pointed out, may require disposing of their members recursively).

(You could get away by simply deleting the items, IF you are absolutely sure noone will access the vector elements anymore before the vector gets deleted - but it is still safer to remove each item before deleting it. This ensure program correctness at any point, eliminating the possibility for subtle bugs and easing maintenance in the long term.)

Btw this is one of the reasons why it is recommended to store smart pointers in collections, instead of raw pointers.

Péter Török
@Péter: Ok, thanks. (Will accept in 10 minutes)
Martijn Courteaux
This includes deleting the contents within the pair you use as a key in your map as well. You can't just delete the pair (if it was allocated with new, though the declaration indicates otherwise) and have the int and string go away.
SB
@SB, good point, thanks; added to the answer.
Péter Török
People like using smart-pointers so much that they often overlook boosts pointer-containers. They are made for this exact scenario.
Space_C0wb0y
+1 For answering the question and pointing out that smart pointers can solve this problem.
Mark B
+4  A: 

You really should consider using smart pointers.

vector<boost::shared_ptr<std::string> >* some_vector = new std::vector<boost::shared_ptr<std::string> >;

some_vector->push_back(boost::shared_ptr<std::string>("Hello World !"));

delete some_vector; // This will delete the contained std::string's as well
some_vector = NULL;

Basically, a smart pointer takes care of the life-cycle of the pointed data. They can even do much more (such a counting references, and so on) but I suggest you read this page to learn more about the different types of smart pointers.

You can even specify a custom "freeing" function to use, instead of the default (delete).

ereOn
Just to mention, since you said you're new to `C++`: if you ever try my code: the space between the two `>` is not part of my coding style: it is **needed** so the compiler doesn't interpret two `>` as the `>>` operator. If you're using `C++0x`, it doesn't matter.
ereOn
@ereOn: Thanks! Again a pitfall discovered for me. Thanks, I will try to remember that.
Martijn Courteaux
A: 

No, you must manually iterate over each container and call delete on the pointers it contains. The vector didn't allocate that memory, so it's not going to clean it up for you.

If you use smart pointers then the pointer itself will handle deallocating it's memory. Otherwise, you must balance your manual allocation with manual deallocation.

meagar
A: 

You may want to consider Boost Pointer Container. It handles all the cleaning up and, in my experience, normal containers can seamlessly (meaning without breaking code) be replaced by these ones.

A pointer container expresses ownership of the contained objects by the container, which is what you have here (otherwise you wouldn't have to clean it up).

A container of smart-pointers is different, because the objects may live longer than the container. Also, there may be a small performance-penalty when using smart-pointers, but that really depends on the size of your containers and the type of operations you perform on them.

Space_C0wb0y