0

When the object a is destroyed, is the personsInHouse map also destroyed or I need to destroy it in destructor? Will it create memory leak if I don't?

class A {
public:
    map<unsigned int, unsigned int> personsInHouse;
};

int main(){
    A a;
   A.hash[10] = 23;
};
amit
  • 175,853
  • 27
  • 231
  • 333
theateist
  • 13,879
  • 17
  • 69
  • 109

2 Answers2

5

The lifetime of personsInHouse is automatic because you are storing it by value, and its lifetime is the lifetime of the parent object. Because you create a by value, its destructor is called when it goes out of scope, and the destructor of an object automatically calls the destructors of the objects it contains. So you do not need to destroy personsInHouse, like you do not need to destroy a.

If personsInHouse was a pointer and you created a map<unsigned int, unsigned int> in dynamic storage with new and stored a pointer to it in personsInHouse, then you would need to manually deallocate the memory that personsInHouse was pointing to in the destructor of A via delete. But that's not the case in the code you posted.

What you have done is the good way to do it: prefer to store every object that you can by value so that you don't have to worry about lifetime management of dynamic objects.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • Technically, the scope of personsInHouse is the sccope of the parent object. But other that the one vocab word, the answer is good. – Mooing Duck Feb 19 '12 at 15:08
  • 1
    @MooingDuck it would be better to say "lifetime", no? I thought scope was more about visibility. And thanks, I added another line about that. – Seth Carnegie Feb 19 '12 at 15:11
  • But lifetime and scope are tightly coupled for objects of automatic storage duration. – Lightness Races in Orbit Feb 19 '12 at 15:45
  • 1
    @LightnessRacesinOrbit that is true, but they are still separate, and I still think the correct word is lifetime – Seth Carnegie Feb 19 '12 at 15:46
  • 1
    @MooingDuck: the scope of `personsInHouse` is *not* the scope of the complete object. Scope is the part of the program in which a name is visible via name lookup (and strictly speaking is a property of the name, not of the object(s) to which the name refers). The scope of `personsInHouse` is the class definition for `A`, plus any function definitions for member functions of `A`, derived classes, etc (in this example there are none). It's also in scope as `a.personsInHouse` in `main`. The scope of `a` is just `main`. Lifetime is a different concept, and it's lifetime that Seth is talking about. – Steve Jessop Feb 19 '12 at 18:19
  • Thats a lot of comments for one wrong vocab word in a comment :) – Mooing Duck Feb 20 '12 at 15:44
4

Yes, it is. When the destructor of a class is run, the destructors of all its members are run. To be precise, the order is:

  1. Body of the destructor is run
  2. All members, in reverse order of construction, are destructed
  3. All non-virtual base classes, in reverse order of construction, are destructed
  4. All virtual base classes, in reverse order of construction, are destructed

In general, if you don't have pointers, you can expect to also not have memory leaks. This is not always the case: you may be using a leaky function, or some function may be performing dynamic allocation and then returning a reference to the object. The situation can be further improved by using smart pointers.

A useful technique for avoiding memory leaks in C++ is RAII: all standard containers follow it, which is why there's no need to explicitly clear() a container before it goes out of scope. The basic principle is to make classes clean up all their resources in their destructors, and then make dedicated classes for that so that most of your classes need not worry about it.

Do note that "class members" are strictly non-static members defined at class scope. If you have

struct S {
    int* p;
};

then p is the only member of S, and when S goes out of scope, p will be destroyed (which doesn't generally involve anything happening, except perhaps an adjustment of the stack pointer). If you at some point do S s; s.p = new int; then p will still be the only member, and the object pointed to by p will not be one, and will therefore not be destroyed when s goes out of scope. For that to happen, you will need to manually do delete s.p;, which corresponds to the general rule of every new needing to have a corresponding delete (idem for new[] and delete[]).

Cactus Golov
  • 3,474
  • 1
  • 21
  • 41
  • What if its members are in dynamic storage? – Luchian Grigore Feb 19 '12 at 15:07
  • 1
    @LuchianGrigore: Then that's not a member, but a member pointer to an object. The pointer is destructed just as I said. – Cactus Golov Feb 19 '12 at 15:09
  • @LuchianGrigore: Members can't be in the heap, they can point to items in the heap (in that case the pointer itself is actually destroyed, but not what it was pointing to) – Jack Feb 19 '12 at 15:09
  • 1
    @Jack members can be in the heap if the parent object is in the heap – Seth Carnegie Feb 19 '12 at 15:12
  • @Seth Carnegie: They could be in the heap as part of another object, but that doesn't change the situation. They'll get destroyed if the parent is destroyed when they are declared by value, wherever they are placed – Jack Feb 19 '12 at 15:13
  • I agree, but I think that for someone who's asking this type of question, a clearer answer might be appropriate. Saying "the destructors of all its members are run" to a newbie might be misleading. – Luchian Grigore Feb 19 '12 at 15:30
  • @LuchianGrigore: If you insist. :P – Cactus Golov Feb 19 '12 at 15:36
  • :) Well if I'd just started with C++, I think I wouldn't understand exactly what you meant. +1 – Luchian Grigore Feb 19 '12 at 15:49
  • @Luchian: part of the problem is that people are sometimes lied to, told that the referand of a pointer member is "a member" of the object that could be separately allocated. Now, Anton might try to take account of the fact that a C++-newbie reader could have been lied to in that way, and hence answer to make it clear that he does mean "members are destroyed", not "referands of members are destroyed" or even "pointer members are deleted". But it's even more important not to humor the lie. – Steve Jessop Feb 19 '12 at 18:25