3

In some classes I have an static std::map with pointers inside. My question is if I need to delete at the end of the program or this memory is automatically freed. My concern is if the pointers stored inside are correctly deleted through our destructors when std::map is deleted.

Thanks.

Killrazor
  • 6,856
  • 15
  • 53
  • 69

7 Answers7

6

If the map contains pointers that were allocated with new (or new[], or malloc), then each pointer needs a corresponding delete (or delete[], or free).

The map's destructor wont know what to do with a bald pointer. Consider using a smart pointer that has appropriate move semantics like a boost smart pointer or if you've got a very new compiler, one of the C++0x smart pointers. However, do not use the current standard's std::auto_ptr, inside of STL containers. See this thread for why.

Edit:

As Billy ONeal pointed out, boost::ptr_map is also designed exactly for this purpose.

Community
  • 1
  • 1
luke
  • 36,103
  • 8
  • 58
  • 81
  • 1
    +1 -- but w.r.t. auto_ptr I would use language stronger than "avoid" given that containers of auto_ptrs should not compile. (And auto_ptr is perfectly okay everywhere else) Also consider `boost::ptr_map`. – Billy ONeal Jan 18 '11 at 16:09
  • Thanks for the help. I think I need to move to boost 1.45 – Killrazor Jan 18 '11 at 21:38
2

If I understand the situation correctly, you don't delete the map itself. But you probably need to delete the objects the map is pointing to. It would probably be a really good idea to use a smart pointer such as Boost shared_ptr in your map instead of native pointers. Then the objects would be cleaned up automatically.

Edit: Using Boost ptr_map might be an even better idea.

Fred Larson
  • 60,987
  • 18
  • 112
  • 174
1

The memory is "automatically freed", in the sense that the entire process memory is freed, but the destructors of the objects pointed to will not be called. This can cause a resource leak, if you use RAII.

Raedwald
  • 46,613
  • 43
  • 151
  • 237
1

std::map never calls delete on it's members. Assuming you're working with a relatively recent operating system, the OS will reclaim the memory occupied by the members on process termination, but the destructors will not run.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
0

If you have a map of pointers, then the answer is 'no', your destructors will not be called, but 'yes', the memory will be freed at the end of process execution. All memory allocated by a process is always freed by the Operating System when a process exits (even if it crashes), but destructors might not be called.

Benoit Thiery
  • 6,325
  • 4
  • 22
  • 28
0

A memory "leak" is where memory is unintentionally not deleted over a period of time, and ends up reducing as the process continues. If it is a type of process that runs for a very long period of time, eg a server that is rarely restarted, this can be a major problem.

Memory leak detectors will pick up on any memory that is allocated and not deleted by a programming call, so valgrind, etc. will report this as a leak.

It is as well to check your code with programs like valgrind, and therefore the less that "gets in the way", the easier it will be to spot real leaks. Therefore my advice is not do just let the system clean up the memory, or singletons, etc, for you when you have allocated a pointer with new (or malloc or new[]).

You can have a "clean-up" routine to do this. Just have an object in the scope of your map that has a deleter (as it will be deleted when it exits) that will clean up the pointers in the map. As you need your object to be deleted first it should be declared later than the map.

CashCow
  • 30,981
  • 5
  • 61
  • 92
-1

Like in any case of storage class which stores pointers: you are responsible to deallocate memory they point to. Storage class is responsible only to clean its own resources. Relying on reclaiming memory by OS at the process termination is a bad practice.

Bojan Komazec
  • 9,216
  • 2
  • 41
  • 51
  • A "storage class" is allowed to do pretty much anything. Now the standard containers don't `delete` anything, but it's perfectly possible to have a container which would nuke it's own members. For example, boost::ptr_map/boost::ptr_vector – Billy ONeal Jan 18 '11 at 16:12
  • @Billy Agree. I used too wide term ("storage class") but I thought on STL containers. – Bojan Komazec Jan 18 '11 at 16:15
  • @Bojan: `boost::ptr_vector` is an STL container, but it certainly nukes it's contents when it is destroyed. (Oh, and I did not downvote) – Billy ONeal Jan 18 '11 at 16:17
  • @Billy: I am not sure I can regard Boost containers as part of STL. They are built on STL. Current C++ standard does not know about Boost but knows about STL (of course, this will be changed with new C++0x). – Bojan Komazec Jan 18 '11 at 16:44
  • @Bojan: The requirements for an STL container are listed in `23.2.1` of the standard. All of the boost pointer container libraries meet the requirements there. They are not in the normal distribution of the STL that is in the standard library, but that does not mean they are not STL containers. – Billy ONeal Jan 18 '11 at 17:35
  • @Billy I must admit I was wrong when I said that "standard knows about STL" because "Standard Template Library" is not mentioned in ISO/IEC 14882:2003 under this name. Basically, we have two things: (1) a part of C++ standard - a set of ISO/IEC 14882:2003 requirements for "Containers library", "Iterators library", "Algorithms library" and function objects (2) STL - a library that implements those requirements (http://en.wikipedia.org/wiki/Standard_Template_Library). You probably misunderstood me as when I said "STL containers" I thought of standard containers - ... – Bojan Komazec Jan 19 '11 at 11:07
  • .../continued/ which are part of the current standard library (they are listed at this Wikipedia article; ptr_vector is of course not among them but vector is) and you thought of any container that implements standard requirements (like boost::ptr_vector). STL will be extended with new Boost conatiners (and probably within namespace std so we'll have std::ptr_vector) in C++0x. Only then ptr_vector could be considered as an STL container. Please correct me if I am missing something. We're all learning here :) – Bojan Komazec Jan 19 '11 at 11:07