1

Is this a good way to delete a map of longs and objects made with new

// iterate over the map for (std::map<unsigned long, Object*>::iterator it = objects.begin(), it_end = objects.end(); it != it_end; ++it) { Object* temp = it->second; if(temp) delete temp; } // clear the map objects.clear(); 
1
  • 2
    Provided that each entry has been new-ed separately (or in other words that there are not two entries with the same value of pointer to object), it is correct. Commented Aug 17, 2011 at 15:14

6 Answers 6

10

Yes. Use boost::ptr_map

boost::ptr_map<std::string, BigObject> data; data.insert("Plop", new BigObject); 

When data goes out of scope it deletes all its value members.
Also for algorithms all members are returned as reference to the object (not pointer) thus it is much easier to use with the standard algorithms than a std::map<std::string, BigObject*> where you would need to de-reference the memebrs before use.

One would have to question why you have a map of pointer to int/long in the first place? Would it not be easier to just to store the value in the map?

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

12 Comments

His map doesn't store pointers to int/long, but to Object classes. I presume it's done for polymorphism.
@sven yes this is correct. My company is very scared of change and I doubt they will allow me to include boost. Thanks for the help though
@Kaiser Wilhelm: boost is practically standard. The boost organization was set up by members so the C++ committee explicitly as a proving ground for things that would likely make it into a future standard. As a result it is one of the most test (trusted) extensions to the standard you can find. Look through the C++ answers on SO; a good majority will have a boost solution that already solved the problem.
@Kaiser Wilhelm: you may be able to use use C++0x smart pointers as per my answer. std::unique_ptr works on VC2010 and g++ 4.6, and if you have g++ 4.5 you can use std::shared_ptr (although std::unique_ptr is supported by g++ 4.5, std::map is not yet move-aware so you can't use it with that; this was fixed in 4.6).
@Kaiser Wilhelm; Too me it seems like overkill that you are doing all this work manually. You should never have to call delete. If you use the correct objects then memory management is automatic. Pointers are a sure sign that you will get it wrong at some point (because their is no ownership semantics associated with a pointer) smart pointers and containers make sure your code is easy to read and exception safe and the specific smart pointer is a way of documenting ownership.
|
4

Yes, although the better solution would be to use smart pointers instead of Object*, but that is a different subject.

You could shorten the content of the for to

{ delete it->second; } 

delete null is defined and is a noop.

Comments

2

It is a perfectly fine way to delete.

Though you can make your life much easier by using a smart pointer.

Comments

2

It's a good start.

Once you've deleted the object, you should either remove the pointer from the map or set it to NULL to avoid dangling pointers. Edit: or of course you could just clear out the map when you're done, as your example shows.

When you store pointers in any of the standard containers, there's always a possibility that an exception or some code error will result in a memory leak. I'd suggest boost pointer containers as an alternative.

Comments

1

Yes. Regardless of what might be considered a design or architecture issue (the use of smarter pointers, for example), it is not unreasonable to use that method to clear the map.

One proviso: the objects map should not by changed by the destruction of the Object* pointers. If it is, it might be better to use something like this:

// iterate over the map typedef std::map<unsigned long, Object*>::iterator map_iter; for (map_iter it = objects.begin(); it != objects.end(); /* blank */ ) { iter_map to_delete = it; ++it; Object* temp = to_delete->second; if(temp) delete temp; objects.delete(to_delete); } 

Comments

1

I would recommend the use of a smart pointer, for example std::unique_ptr (this is a C++0x feature, not all compilers support it yet). For example:

std::map<unsigned long, std::unique_ptr<Object>> map; // Do something with the map map.clear(); // The objects are automatically deleted. 

You can also use std::shared_ptr (or boost::shared_ptr if your compiler doesn't support C++0x smart pointers), which has the advantage that it will work if your map can contain the same pointer more than once, and your objects won't be destroyed if someone else still has a pointer to them.

boost::ptr_map is also an options, though I believe that, like the manual approach, will not work right if the map contains the same pointer more than once.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.