Can a dtor be called more than ctor?

P

peifeng_w

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.
 
A

Alf P. Steinbach

* (e-mail address removed):
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.
 
K

Kai-Uwe Bux

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.
 
P

peifeng_w

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.
 
A

Alf P. Steinbach

* (e-mail address removed):
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.
 
K

Kai-Uwe Bux

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top