[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

destructors

cronusf

10/15/2008 4:21:00 AM

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?
11 Answers

george.priv

10/15/2008 4:24:00 AM

0

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

Jerry

10/15/2008 6:40:00 AM

0

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.

Kai-Uwe Bux

10/15/2008 7:11:00 AM

0

cronusf@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

Salt_Peter

10/15/2008 7:12:00 AM

0

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()

Salt_Peter

10/15/2008 7:15:00 AM

0

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.

Kai-Uwe Bux

10/15/2008 7:27:00 AM

0

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

anon

10/15/2008 8:21:00 AM

0

Kai-Uwe Bux wrote:
> cronusf@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;
}

Kai-Uwe Bux

10/15/2008 8:37:00 AM

0

anon wrote:

> Kai-Uwe Bux wrote:
>> cronusf@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

george.priv

10/15/2008 1:00:00 PM

0

On Oct 15, 3:14 am, Salt_Peter <pj_h...@yahoo.com> 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.

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

Salt_Peter

10/15/2008 2:15:00 PM

0

On Oct 15, 8:59 am, george.p...@gmail.com wrote:
> On Oct 15, 3:14 am, Salt_Peter <pj_h...@yahoo.com> 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.
>
> 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()