0
class Foo{
public:
    Foo(){
        cout <<"C ";
    }
    ~Foo(){
        cout <<"D ";
    }
};

void func(){
    Foo* p = new Foo;
    p = NULL;
}

int main(){
    Foo a;
    for (int i=0; i<1; i++){
        Foo b;
        if (true){
            Foo c;
        }
        func();
    }
    return 0;
}

For this question, the output is C C C D C D D, and if I delete the func() in the main function, the output become C C C D D D, I understand the first 3 C where it come from, but I don't understand the remaining, please explain it, thanks.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
kdhug886
  • 47
  • 1
  • 5
  • `for (int i=0; i<1; i++)` essentially executes it's block once, so does `if(true)`. If you want to define a scope, you can simply use a pair of braces (`{ }`). You do not need to use them in the context of a flow control statement, You could simply do `int main(){ Foo a; { Foo b; { Foo c; } func(); } return 0; }` – François Andrieux May 19 '17 at 19:13
  • 2
    Stepping through this with a debugger might help... – Borgleader May 19 '17 at 19:13
  • `p = NULL;` doesn't actually destroy the object. The `new Foo` object is leaked. This line should read `delete p;`. – cdhowie May 19 '17 at 19:16
  • It seems you are confused about what a destructor does and how object life time work. This is pretty fundamental stuff for c++, best covered by a [good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – François Andrieux May 19 '17 at 19:17
  • 1
    If you'd add some debug message, you'd notice that the ctors are for abcp and dtors for cba in the order of exiting scope. P leaks. – Aki Suihkonen May 19 '17 at 19:18

4 Answers4

3

The scope of the object a is the scope of the outer code block of the function main. It is the first object that is created and the last object that is deleted.

int main(){
    Foo a;
    // ...
    return 0;
}

C C C D C D D
|           |
a           a

Then in the for loop that has only one iteration there is created the object b that is deleted after the first iteration of the loop

for (int i=0; i<1; i++){
    Foo b;
    // ...
}

C C C D C D D
| |       | |
a b       b a

Then in the block scope of the statement if

    if (true){
        Foo c;
    }

there is created and deleted the object c

C C C D C D D
| | | |   | |
a b c c   b a

After that the function func is called

func();

Inside the function there is created an unnamed object using the operator new and pointed to by the pointer p.

void func(){
    Foo* p = new Foo;
    p = NULL;
}

C C C D C D D
| | | | | | |
a b c c p b a

This object is not deleted because the operator delete is not called for this object. So there is a memory leak.

That is all.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2
  1. C - a is constructed
  2. C - b is constructed
  3. C - c is constructed
  4. D - c is desctructed becouse you leave the scope
  5. C - an object Foo is dynamically allocated and pointed to by p, but since it is dynamically allocated, and never deleted, it's never destructed.
  6. D - b is destructed
  7. D - a is destructed
sigvaldm
  • 564
  • 4
  • 15
1

There order would be for C C C D C D D:

  1. C - Construct A
  2. C - Construct B
  3. C - Construct C
  4. D - Destruct C
  5. C - Construct p (in func)
  6. D - Destruct B
  7. D - Destruct A

// memleak for p (in func)

Joseph D.
  • 11,804
  • 3
  • 34
  • 67
0

When the func(); call is included, the steps taken are:

Foo a; -> C

Foo b; -> C

Foo c; -> C

Left the scope of Foo c -> D

func(); call ->
    new Foo; -> C

Finished func() call, left the scope of Foo b -> D

Left the scope of Foo a -> D

Note that the Foo object created in func() is never destructured, meaning you have a memory leak.

Gavin
  • 4,365
  • 1
  • 18
  • 27