473,396 Members | 2,076 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,396 software developers and data experts.

destructors

If you have:

#include <iostream>

using namespace std;

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

int x;
};

class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}

int y;
int z;
};

int main()
{
Base* b = new Derived;
delete b;
}

Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?
Oct 15 '08 #1
11 1788
On Oct 15, 12:20*am, cron...@gmail.com wrote:
If you have:

#include <iostream>

using namespace std;

*class Base
{
public:
* * ~Base()
* * * * {
* * * * * * * * cout << "~Base()" << endl;
* * * * }

* * int x;

};

class Derived : public Base
{
public:
* * * * ~Derived()
* * * * {
* * * * * * * * cout << "~Derived()" << endl;
* * * * }

* * int y;
* * int z;

};

int main()
{
* * Base* b = new Derived;
* * delete b;

}

Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?
Yes
Oct 15 '08 #2
On Oct 15, 12:24*pm, george.p...@gmail.com wrote:
On Oct 15, 12:20*am, cron...@gmail.com wrote:


If you have:
#include <iostream>
using namespace std;
*class Base
{
public:
* * ~Base()
* * * * {
* * * * * * * * cout << "~Base()" << endl;
* * * * }
* * int x;
};
class Derived : public Base
{
public:
* * * * ~Derived()
* * * * {
* * * * * * * * cout << "~Derived()" << endl;
* * * * }
* * int y;
* * int z;
};
int main()
{
* * Base* b = new Derived;
* * delete b;
}
Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?

Yes
I don't think so.
To free y and z you must change ~Base() to virtual.
Oct 15 '08 #3
cr*****@gmail.com wrote:
If you have:

#include <iostream>

using namespace std;

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

int x;
};

class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}

int y;
int z;
};

int main()
{
Base* b = new Derived;
delete b;
}

Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?
When delete is called you have undefined behavior as per [5.3.5/3]. In
particular, all bets are off with respect to the memory of the variables y
and z.
Best

Kai-Uwe Bux
Oct 15 '08 #4
On Oct 15, 12:20 am, cron...@gmail.com wrote:
If you have:

#include <iostream>

using namespace std;

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

int x;

};

class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}

int y;
int z;

};

int main()
{
Base* b = new Derived;
delete b;

}

Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?
No it won't.
If you had used a smart pointer like boost::shared_ptr:

#include "boost/shared_ptr.hpp"

....

int main()
{
boost::shared_ptr< Base bsp(new Derived);
// no delete needed
}

output:

~Derived()
~Base()

Oct 15 '08 #5
On Oct 15, 12:24 am, george.p...@gmail.com wrote:
On Oct 15, 12:20 am, cron...@gmail.com wrote:
If you have:
#include <iostream>
using namespace std;
class Base
{
public:
~Base()
{
cout << "~Base()" << endl;
}
int x;
};
class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}
int y;
int z;
};
int main()
{
Base* b = new Derived;
delete b;
}
Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?

Yes
No, absolutely not
this test case proves it, ~Derived() is not invoked.
Oct 15 '08 #6
Salt_Peter wrote:
On Oct 15, 12:24 am, george.p...@gmail.com wrote:
>On Oct 15, 12:20 am, cron...@gmail.com wrote:
If you have:
#include <iostream>
using namespace std;
class Base
{
public:
~Base()
{
cout << "~Base()" << endl;
}
int x;
};
class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}
int y;
int z;
};
int main()
{
Base* b = new Derived;
delete b;
}
Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?

Yes

No, absolutely not
this test case proves it, ~Derived() is not invoked.
a) The destructor is not involved in freeing the memory for y and z. That
would be an issue for the deallocation function invoked by delete.

b) One has undefined behavior anyway [5.3.5/3] in the test case, so it
proves nothing.
Best

Kai-Uwe Bux
Oct 15 '08 #7
Kai-Uwe Bux wrote:
cr*****@gmail.com wrote:
>If you have:

#include <iostream>

using namespace std;

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

int x;
};

class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}

int y;
int z;
};

int main()
{
Base* b = new Derived;
delete b;
}

Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?

When delete is called you have undefined behavior as per [5.3.5/3]. In
particular, all bets are off with respect to the memory of the variables y
and z.
Sorry to hijack the tread, but is next example UB as well?

// POD structure
struct A
{
int a;
};

template< typename T >
struct B : public T
{
int b;
};

int main()
{
B< A *inst = new B< A >;
A &copy = *inst;

inst->b = 2;
copy.a = 3;

delete inst;
}
Oct 15 '08 #8
anon wrote:
Kai-Uwe Bux wrote:
>cr*****@gmail.com wrote:
>>If you have:

#include <iostream>

using namespace std;

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

int x;
};

class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}

int y;
int z;
};

int main()
{
Base* b = new Derived;
delete b;
}

Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?

When delete is called you have undefined behavior as per [5.3.5/3]. In
particular, all bets are off with respect to the memory of the variables
y and z.

Sorry to hijack the tread, but is next example UB as well?

// POD structure
struct A
{
int a;
};

template< typename T >
struct B : public T
{
int b;
};

int main()
{
B< A *inst = new B< A >;
A &copy = *inst;

inst->b = 2;
copy.a = 3;

delete inst;
}
No undefined behavior that I would see. However, with

A* inst = new B< A >;
...
delete inst;

you would violate [5.3.5/3] as the static type and the dynamic type differ
but the base A does not have a virtual destructor.

BTW: that the types are POD is unrelated.
Best

Kai-Uwe Bux
Oct 15 '08 #9
On Oct 15, 3:14*am, Salt_Peter <pj_h...@yahoo.comwrote:
On Oct 15, 12:24 am, george.p...@gmail.com wrote:
On Oct 15, 12:20 am, cron...@gmail.com wrote:
If you have:
#include <iostream>
using namespace std;
*class Base
{
public:
* * ~Base()
* * * * {
* * * * * * * * cout << "~Base()" << endl;
* * * * }
* * int x;
};
class Derived : public Base
{
public:
* * * * ~Derived()
* * * * {
* * * * * * * * cout << "~Derived()" << endl;
* * * * }
* * int y;
* * int z;
};
int main()
{
* * Base* b = new Derived;
* * delete b;
}
Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?
Yes

No, absolutely not
this test case proves it, ~Derived() is not invoked.
Automatic members will be deallocated outside of the user-provided
destructor similar to allocating deallocating by malloc/free. If y, z
would be a pointers allocated within the lifetime of Derived object
and deallocated by Derived::~Derived(), then you will get a memory
leak.

Regards, George
Oct 15 '08 #10
On Oct 15, 8:59 am, george.p...@gmail.com wrote:
On Oct 15, 3:14 am, Salt_Peter <pj_h...@yahoo.comwrote:
On Oct 15, 12:24 am, george.p...@gmail.com wrote:
On Oct 15, 12:20 am, cron...@gmail.com wrote:
If you have:
#include <iostream>
using namespace std;
class Base
{
public:
~Base()
{
cout << "~Base()" << endl;
}
int x;
};
class Derived : public Base
{
public:
~Derived()
{
cout << "~Derived()" << endl;
}
int y;
int z;
};
int main()
{
Base* b = new Derived;
delete b;
}
Only ~Base() is called, which is expected since it is not virtual.
However, when delete is called, will it free the memory allocated for
the variables y and z?
Yes
No, absolutely not
this test case proves it, ~Derived() is not invoked.

Automatic members will be deallocated outside of the user-provided
destructor similar to allocating deallocating by malloc/free. If y, z
would be a pointers allocated within the lifetime of Derived object
and deallocated by Derived::~Derived(), then you will get a memory
leak.

Regards, George
The members are not automatic:

#include <iostream>

class Member
{
public:
~Member()
{
std::cout << "~Member()" << std::endl;
}
};

class Base
{
Member m;
public:
~Base()
{
std::cout << "~Base()" << std::endl;
}
};

class Derived : public Base
{
Member m;
public:
~Derived()
{
std::cout << "~Derived()" << std::endl;
}
};

int main()
{
Base* p_b = new Derived;

delete p_b;
}

output:

~Base()
~Member()

With virtual ~dtor:

~Derived()
~Member()
~Base()
~Member()
Oct 15 '08 #11
On Oct 15, 10:14*am, Salt_Peter <pj_h...@yahoo.comwrote:
On Oct 15, 8:59 am, george.p...@gmail.com wrote:
On Oct 15, 3:14 am, Salt_Peter <pj_h...@yahoo.comwrote:
On Oct 15, 12:24 am, george.p...@gmail.com wrote:
On Oct 15, 12:20 am, cron...@gmail.com wrote:
If you have:
#include <iostream>
using namespace std;
*class Base
{
public:
* * ~Base()
* * * * {
* * * * * * * * cout << "~Base()" << endl;
* * * * }
* * int x;
};
class Derived : public Base
{
public:
* * * * ~Derived()
* * * * {
* * * * * * * * cout << "~Derived()" << endl;
* * * * }
* * int y;
* * int z;
};
int main()
{
* * Base* b = new Derived;
* * delete b;
}
Only ~Base() is called, which is expected since it is not virtual..
However, when delete is called, will it free the memory allocatedfor
the variables y and z?
Yes
No, absolutely not
this test case proves it, ~Derived() is not invoked.
Automatic members will be deallocated outside of the user-provided
destructor similar to allocating deallocating by malloc/free. *If y, z
would be a pointers allocated within the lifetime of Derived object
and deallocated by Derived::~Derived(), then you will get a memory
leak.
Regards, George

The members are not automatic:

#include <iostream>

class Member
{
public:
* ~Member()
* {
* * std::cout << "~Member()" << std::endl;
* }

};

class Base
{
* Member m;
public:
* ~Base()
* {
* * std::cout << "~Base()" << std::endl;
* }

};

class Derived : public Base
{
* Member m;
public:
* ~Derived()
* {
* * std::cout << "~Derived()" << std::endl;
* }

};

int main()
{
* Base* p_b = new Derived;

* delete p_b;

}

output:

~Base()
~Member()

With virtual ~dtor:

~Derived()
~Member()
~Base()
~Member()
Correct, in your example compiler has no idea that m needs destructor
to be called, but it's memory will be freed nonetheless even without
calling ~Member().

G.
Oct 15 '08 #12

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

Similar topics

3
by: Rajesh Garg | last post by:
Can we have private constructors and destructors? IF yes what is the use of such constructors or destructors.....in the sense where can these be implemented in a system................. I have...
3
by: Nuno Barros | last post by:
Cn someone tell me if when i call the destructor of a derivated class, the destructor of the base class is called implicitly? Or shall i call the destructor by myself? Thanks in advance ...
12
by: Ross Boylan | last post by:
I am trying to understand under what circumstances destructors get called with std::vector. I have an application in which I will put real objects, not just pointers, in the vector. 1. The...
8
by: johny smith | last post by:
If I have a simple class with say a couple of integers only is there any need for me to provide a destructor? thanks!
7
by: qazmlp | last post by:
When a member function is declared as virtual in the base class, the derived class versions of it are always treated as virtual. I am just wondering, why the same concept was not used for the...
26
by: Michi Henning | last post by:
I've been having problem with destructors in the context of having ported C# code developed under .NET to Mono. What happens is that, on a dual-CPU machine, various parts of the code crash randomly...
8
by: Edward Diener | last post by:
I have a __value class which uses some legacy C++ code. So I wrapped the legacy C++ code in another __nogc class and have a pointer to that class as a member of my __value class. When the __value...
3
by: alex.gman | last post by:
If I have code like this int f() { // ... stuff ... g(); if(x > 0) return (x+4); // ... more stuff ... always_call(z); return y; }
6
by: mlw | last post by:
Could someone explain why there is no destructor in Java classes? There are many times you need to be called WHEN an object goes out of scope and not when it will eventally be freed.
6
by: Jeff Newman | last post by:
Hello, Could anyone explain to me why the following class's destructor shows up as having multiple branches? (At least as judged by gcov 4.1.2 when compiled with gcc 4.1.2 ): struct blah {...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.