Can a dtor be called more than ctor?

Discussion in 'C++' started by peifeng_w@hotmail.com, Nov 26, 2006.

  1. Guest

    Hi, try the following code with flag=0/1/2.

    #include<iostream>

    using namespace std;

    #define flag 2//option:0,1,2

    class C
    {
    public:
    C(){cout<<"C"<<endl;}
    #if flag==1
    C(C&){cout<<"C"<<endl;}
    #endif
    virtual ~C(){cout<<"~C"<<endl;}
    };

    #if flag==0
    void myfunc(C)
    {
    }
    #elif flag==1
    void myfunc(C)
    {
    }
    #elif flag==2
    void myfunc(C&)
    {
    }
    #endif

    int _tmain(int argc, _TCHAR* argv[])
    {
    cout<<"flag="<<flag<<endl;
    C myC;
    myfunc(myC);
    return 0;
    }


    /*
    result:

    flag=0
    C
    ~C
    ~C

    flag=1
    C
    C
    ~C
    ~C

    flag=2
    C
    ~C
    */

    It really surprized me that when flag=0, I got C called once with ~C
    called twice. I know that if more ctor are called than dtor, then there
    is a memory leak. But what happened when more dtor is called than ctor?
    Does anybody know relevant specification in C++ standard? I am using
    VS.net 2003. Thanks.
    , Nov 26, 2006
    #1
    1. Advertising

  2. * :
    > Hi, try the following code with flag=0/1/2.


    Better use meaningful names than magic numbers like 0, 1 and 2.


    > #include<iostream>
    >
    > using namespace std;
    >
    > #define flag 2//option:0,1,2
    >
    > class C
    > {
    > public:
    > C(){cout<<"C"<<endl;}
    > #if flag==1
    > C(C&){cout<<"C"<<endl;}
    > #endif
    > virtual ~C(){cout<<"~C"<<endl;}
    > };


    Why is the diagnostic output for copy construction limited to flag=1?


    > #if flag==0
    > void myfunc(C)
    > {
    > }
    > #elif flag==1
    > void myfunc(C)
    > {
    > }
    > #elif flag==2
    > void myfunc(C&)
    > {
    > }
    > #endif
    >
    > int _tmain(int argc, _TCHAR* argv[])


    This is not standard C++. It should not compile. In standard C++ you have

    int main()

    See, it's even less to write! ;-)


    > {
    > cout<<"flag="<<flag<<endl;
    > C myC;
    > myfunc(myC);
    > return 0;
    > }
    >
    >
    > /*
    > result:
    >
    > flag=0
    > C
    > ~C
    > ~C
    >
    > flag=1
    > C
    > C
    > ~C
    > ~C
    >
    > flag=2
    > C
    > ~C
    > */
    >
    > It really surprized me that when flag=0, I got C called [only] once


    Depends what you mean by "C". There are two constructor calls but only
    one default constructor call.


    > with ~C
    > called twice.


    The destructor is also, with your compiler etc., called twice for
    flag=1, according to the output above.

    It's no mystery.

    'myfunc' takes a C argument by value, which means a copy is (logically)
    made, which means a separate C object whose destructor must be called.


    > I know that if more ctor are called than dtor, then there
    > is a memory leak.


    No, that's an unwarranted conclusion, and anyway it's not what's
    happening here. However, /if/ this happens then you're off in Undefined
    Behavior land, so anything might happen. Depends on compiler etc..


    > But what happened when more dtor is called than ctor?


    You mean above?

    What happended was that your code displayed "~C" twice and "C" only once.

    Then you drew untenable conclusions from your program's less than
    complete diagnostic output.


    > Does anybody know relevant specification in C++ standard?


    Yes. If you don't do fancy things with very low-level features, you'll
    get exactly as many destructor calls as /successful/ constructor calls.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 26, 2006
    #2
    1. Advertising

  3. Kai-Uwe Bux Guest

    wrote:

    > Hi, try the following code with flag=0/1/2.
    >
    > #include<iostream>
    >
    > using namespace std;
    >
    > #define flag 2//option:0,1,2
    >
    > class C
    > {
    > public:
    > C(){cout<<"C"<<endl;}
    > #if flag==1
    > C(C&){cout<<"C"<<endl;}
    > #endif
    > virtual ~C(){cout<<"~C"<<endl;}
    > };
    >
    > #if flag==0
    > void myfunc(C)
    > {
    > }
    > #elif flag==1
    > void myfunc(C)
    > {
    > }
    > #elif flag==2
    > void myfunc(C&)
    > {
    > }
    > #endif
    >
    > int _tmain(int argc, _TCHAR* argv[])
    > {
    > cout<<"flag="<<flag<<endl;
    > C myC;
    > myfunc(myC);
    > return 0;
    > }
    >
    >
    > /*
    > result:
    >
    > flag=0
    > C
    > ~C
    > ~C
    >
    > flag=1
    > C
    > C
    > ~C
    > ~C
    >
    > flag=2
    > C
    > ~C
    > */
    >
    > It really surprized me that when flag=0, I got C called once with ~C
    > called twice.


    You constructed two objects of type C and both got destructed. It just so
    happens that you did not see the construction of the second one since when
    flag != 1 the copy constructor does not print anything.

    > I know that if more ctor are called than dtor, then there
    > is a memory leak. But what happened when more dtor is called than ctor?


    Undefined behavior. However, this simply did not happen in your code.

    > Does anybody know relevant specification in C++ standard?


    Sure: [12.4/14]

    Once a destructor is invoked for an object, the object no longer exists;
    the behavior is undefined if the destructor is invoked for an object whose
    lifetime has ended (3.8). [Example: if the destructor for an automatic
    object is explicitly invoked, and the block is subsequently left in a
    manner that would ordinarily invoke implicit destruction of the object,
    the behavior is undefined. ]


    > I am using VS.net 2003.


    Irrelevant in this news group.
    Kai-Uwe Bux, Nov 26, 2006
    #3
  4. Guest

    Maybe I didn't make myself clear in the initial post. I am asking why
    in the following code, the ctor is called once while the dtor is called
    twice.
    In my mind, every ctor called should have a unique dtor called. so the
    ctor and dtor always get paired. (correct me if I was wrong.) But in
    the following code, I did nothing low level, just simple c++, the
    resulting code calls dtor more than ctor. if one is doing housekeeping
    in ctor and dtor, then things may go wild.
    The following code is when flag=0 in my first post. In that post,
    flag=1/2 was given to show that if a copy ctor is present, or if myfunc
    is using reference, then the ctor and dtor get paired.
    My question:
    1. Is the following code valid? if yes, then why the ctor is called
    once while the dtor is called twice? if no, what is wrong? what does
    the c++ standard say?
    2. Shouldn't c++ demand a copy ctor?(it is only recommended)
    2. Shouldn't c++ demand that a fnction uses a reference?

    #include<iostream>

    using namespace std;

    class C
    {
    public:
    C(){cout<<"C"<<endl;}
    virtual ~C(){cout<<"~C"<<endl;}
    };

    void myfunc(C)
    {
    }

    int main()//int _tmain(int argc, _TCHAR* argv[])
    {
    C myC;
    myfunc(myC);
    return 0;
    }

    /*
    C
    ~C
    ~C
    */

    Thanks.
    , Nov 29, 2006
    #4
  5. * :
    > Maybe I didn't make myself clear in the initial post. I am asking why
    > in the following code, the ctor is called once while the dtor is called
    > twice.


    You've got two competent people answering that already, and the answer
    was: it ain't so.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Nov 29, 2006
    #5
  6. Kai-Uwe Bux Guest

    wrote:

    > Maybe I didn't make myself clear in the initial post.


    You did.

    > I am asking why in the following code, the ctor is called once while the
    > dtor is called twice.


    It isn't. Same as in your original post: you have two constructor calls and
    two destructor calls.

    > In my mind, every ctor called should have a unique dtor called. so the
    > ctor and dtor always get paired. (correct me if I was wrong.)


    Here, you are right.

    > But in
    > the following code, I did nothing low level, just simple c++, the
    > resulting code calls dtor more than ctor.


    It does not.

    [snip]
    > My question:
    > 1. Is the following code valid?


    Yes.


    > if yes, then why the ctor is called once while the dtor is called twice?


    In the code below, there are *two* constructor calls and two destructor
    calls. One constructor call is the call of the default constructor, which
    prints some output, the other call is the call of the copy constructor,
    which goes undetected.

    > if no, what is wrong? what does the c++ standard say?


    The if yes branch of the question was taken, therefore, this part requires
    no answer.


    > 2. Shouldn't c++ demand a copy ctor?(it is only recommended)


    Where did you read that a copy constructor is recommended?

    The compiler generates a copy constructor for you if you do not define one
    yourself. This is what happens in the code below: the copy constructor is
    called, but does not print any thing.


    > 2. Shouldn't c++ demand that a fnction uses a reference?


    No.


    > #include<iostream>
    >
    > using namespace std;
    >
    > class C
    > {
    > public:
    > C(){cout<<"C"<<endl;}
    > virtual ~C(){cout<<"~C"<<endl;}
    > };
    >
    > void myfunc(C)
    > {
    > }
    >
    > int main()//int _tmain(int argc, _TCHAR* argv[])
    > {
    > C myC;
    > myfunc(myC);


    In passing the argument to myfunc by value, the copy constructor is called.

    > return 0;
    > }
    >
    > /*
    > C
    > ~C
    > ~C
    > */



    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Nov 29, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jacques Labuschagne

    Explicit ctor/dtor calls

    Jacques Labuschagne, Jul 20, 2003, in forum: C++
    Replies:
    3
    Views:
    345
    Michael Kochetkov
    Jul 20, 2003
  2. Karl Heinz Buchegger

    Ctor/Dtor order

    Karl Heinz Buchegger, Jul 30, 2003, in forum: C++
    Replies:
    3
    Views:
    1,232
    Greg Comeau
    Jul 30, 2003
  3. Apricot
    Replies:
    4
    Views:
    524
    velthuijsen
    Apr 16, 2004
  4. pmastroianni

    Does a ctor/dtor occupy memory

    pmastroianni, Apr 1, 2005, in forum: C++
    Replies:
    1
    Views:
    351
    Howard
    Apr 1, 2005
  5. Grizlyk
    Replies:
    8
    Views:
    484
    Grizlyk
    Nov 29, 2006
Loading...

Share This Page