1

I have query regarding std::map.

if I have a std::map like:

std::map <T1, T2*> my_map; T1 t; T2* tt = new T2; my_map[t]=tt; 

who is responsible to clean this container, Will destructor of T2 will take care of it (T2* tt). Also if I want to retain this container throughout the program, where should I clean it.

Thanks

0

5 Answers 5

5

The map destroys the objects stored in the map. The map stores some T1 objects, which will be destroyed, and it stores some T2 pointers, which will be destroyed.

But it does not store actual T2 objects. So no T2 objects will be destroyed.

Raw pointers do not have ownership of the objects they point to. So when a pointer is destroyed, it will not delete whatever it points to.

Generally speaking, when you have a pointer, there is no way to know if

  • it points to a valid object at all (you don't want to call delete on some random garbage in memory),
  • the object it points to has been allocated with new (if it has been allocated in another way, it should not be deleted with delete), or
  • if there are other pointers that also point to the same object (in which case only one of them should call delete. Which one?)

So even if you wanted to, there is no way to automatically delete an object when a pointer to it is destroyed.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 because this answer is really well written, in-depth, and understandable.
4

The destructor of T2 is called nowhere in this example, only the pointer is destroyed. When the map is out of scope, it will destroy all pairs of elements <T1, T2*>, but this will not call delete on the second item.

You could however use boost::shared_ptr or std::shared_ptr (C++11) if you want reference-counted pointers.

#include <boost/shared_ptr.hpp> std::map <T1, boost::shared_ptr<T2> > my_map; T1 t; T2 *tt = new T2; my_map[t] = tt; // tt is passed to a shared_ptr, ref count = 1 // when out of scope, the destructor of `boost::shared_ptr` will call `delete`. 

If you needn't make copies of the objects stored in the map, you can use C++11's std::unique_ptr.

3 Comments

In C++11, unique_ptr would be more suitable than shared_ptr, since shared ownership isn't required.
@Mike Seymour: with unique_ptr some algorithms might be unavailable (that make an object copy) since unique_ptr(unique_ptr&) = delete;.
@Benoit: but until you know you need shared ownership, I'd prefer to default to the safer, more restricted, unique_ptr. It's easier to relax the ownership rules later on, than it is to try to tighten them.
1

What Benoit said; but as an alternative consider a boost::ptr_map; basically a map which takes ownership of contained pointer values.

Comments

0

It's up to you to decide who is responsible to clean data, depending on what is your intent (for instance, your map can be a temporary storage to help perform some algorithm and you want to avoid copies). However, using boost::shared_ptr (or std::tr1::shared_ptr) is often the good way to go.

Comments

-1

This object is a local variable created in the stack(in other words not in the heap). Once it's out of scope, it will be destroyed.

To explain a bit more, when you create an object with new operator it's created in the heap, and you have to manually delete it. When you instantiate it like AClass a this will be created in the stack and when the program flow gets out of the scope it's created it will be destroyed automatically.

2 Comments

Did I say so? Ruchi asks who cleans up the container? And container std::map <T1, T2*> my_map; is created in the stack.
"Will destructor of T2 will take care of it (T2* tt)", your answer is now true (after the edit) but you should probably change "This object" to "The std::map" since it's a bit vague at the moment. Also only part of the std::map is on the stack, it's backed by the heap and it's own destructor will clear that up when it goes out of scope.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.