473,385 Members | 1,732 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Can a dtor be called more than ctor?

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 '06 #1
5 1776
* pe*******@hotmail.com:
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?
Nov 26 '06 #2
pe*******@hotmail.com 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.
Nov 26 '06 #3
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 '06 #4
* pe*******@hotmail.com:
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?
Nov 29 '06 #5
pe*******@hotmail.com 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
Nov 29 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Jacques Labuschagne | last post by:
Hi all, Is it legal to kill an object and build a new one of the same type in its memory? class A{ int i; public: explicit A(int value): i(value){} };
1
by: pmastroianni | last post by:
When a class is instantiated, will the ctor and dtor occupy memory? IF ctor and dtor do occupy memory of an instantiated class where would they be in memeory?
27
by: tuvok | last post by:
Is it correct that the virtual dtor of base gets called implicitly? Here's some code to demonstrate what I mean: Class B has a virtual destructor, so has class D which is derived from B. Deleting...
8
by: Grizlyk | last post by:
Good morning. Look here: http://groups.google.com/group/fido7.ru.cpp.chainik/browse_frm/thread/7341aba5238c0f79 and here:...
7
by: Adam Nielsen | last post by:
Hi everyone, I'm having some trouble getting the correct chain of constructors to be called when creating an object at the bottom of a hierarchy. Have a look at the code below - the inheritance...
15
by: subramanian100in | last post by:
consider the following program: #include <iostream> using namespace std; class Test { public: Test(int xx) : x(xx) { cout << x << endl; }
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.