pouët.net

derived class deletion

category: code [glöplog]
I know this is beginner stuff but I need confirmation.
Consider the following:

struct Base
{
~Base() {}
virtual void Execute() = 0;
};

struct Derived : public Base
{
~Derived() {}
void Execute() {}
};

struct DerivedWithData : public Base
{
int mData;

~DerivedWithData() {}
void Execute() {}
};

//example 1
Base* a = new Derived;
delete a;
//example 2
Base* a = new DerivedWithData;
delete a;

Now I'm aware that the derived class destructors wont be called because the base class destructor is not virtual.

Still, are both examples leaking memory?

Or in other words, do you need a virtual destructor for the delete operator to deallocate the correct amount?
added on the 2010-07-30 22:21:33 by duffman duffman
Quote:

Still, are both examples leaking memory?

yes, both destructors wont be called.

Quote:

do you need a virtual destructor for the delete operator to deallocate the correct amount?

yes ~Base() {} should be virtual.
added on the 2010-07-30 22:36:08 by panic panic
thanks
added on the 2010-07-30 22:54:10 by duffman duffman
Those particular examples won't leak memory. The destructor isn't the part of an object that frees the memory the object has been using. And delete ultimately passes a void* to free, so it will release correct amount of memory regardless.

What delete won't do is figure out the full class of the object you're deleting, so if you pass a pointer to the base class, only the base class destructor is called. That will cause a resource leak if the derived class owns resources that are supposed to be released by its destructor, such as file handles or pointers to other objects, but it makes no difference if the destructor is empty anyway and all the member variables are fundamental types like int.

If the base class destructor is virtual, though, then the destructor call happens much like a virtual method call (note that the derived class still calls the base class destructor, so you're "chaining" the destructors rather than overriding).

The general rule is that any class with virtual methods should have a virtual destructor, too. There are still cases, though, where a class without virtual methods should have a virtual destructor. On the other hand, if you always make destructors virtual to be on the safe side, there is a performance penalty.
added on the 2010-07-31 17:10:07 by doomdoom doomdoom
to give an example:

Code: struct Base { int * pBaseData; Base() { pBaseData = new int[100]; } ~Base() { delete[] pBaseData; } virtual void Execute() = 0; }; struct Derived : public Base { ~Derived() {} void Execute() {} }; struct DerivedWithData : public Base { int * pData; DerivedWithData() { pData = new int[10]; } ~DerivedWithData() { delete[] pData; } void Execute() {} }; //example 1 Base* a = new Derived; delete a; //example 2 Base* a = new DerivedWithData; delete a;


THIS will leak memory.
added on the 2010-07-31 17:26:55 by Gargaj Gargaj
stuct's are so 1980.
Quote:
On the other hand, if you always make destructors virtual to be on the safe side, there is a performance penalty.


Then again, as soon as you notice the "performance penalty" from routing destructor calls through one level of indirection at all, you can be pretty sure you've got way, WAY bigger problems with the way you structured your code. :)
added on the 2010-07-31 21:33:19 by kb_ kb_
Just make all your destructor virtual and ask yourself why this isn't the default. Or rather do not. Code a demo instead.
added on the 2010-08-01 00:27:56 by _-_-__ _-_-__
not exactly the same, but maybe some ppl dont know about this page yet and especially that small portion of code that can help a lot:
Iterate & Delete
rest of the page is helpful for every coder aswell, thanx chaos :)
well,maybe i wanted to post this first:
http://xyzw.de/c150.html
^as said, its all useful on chaos page ! ♥
Memory Leaks
sorry, dunno if i correctly implemented the earlier post with BB, got that plugin making any link clinkable...
Quote:
http://xyzw.de/c150.html


Is that what windows programmers do instead of Valgrind?
added on the 2010-08-01 02:10:25 by LiraNuna LiraNuna
Valgrind? Is that what Linux programmers do instead of having a HTTP server that shows live memory usage sorted by all kinds of criteria while the program is running at normal speed?
added on the 2010-08-01 04:29:53 by kb_ kb_
Quote:

Still, are both examples leaking memory?

Or in other words, do you need a virtual destructor for the delete operator to deallocate the correct amount?
An even better question is: Why do you care? :D

I guess it won't leak memory since the parent class isn't storing any actual data.
Actually, example 2 is going to leak. Example 1 is not going to leak.
http://xyzw.de/c130.html
that's a genius way of performance optimizing :O
added on the 2010-08-01 07:06:32 by panic panic
Doom : your explanation makes sense, that's what I thought first. The internal memory manager has to keep track of the allocation size anyway.

The reason I care is because of executable size, not performance.
added on the 2010-08-01 07:32:16 by duffman duffman
duff, if you're doing size optimized coding and still need deconstructors - then you're doing it wrong. ExitProcess cleans up nicely.
Exactly. The OS is your perfect deallocator. And for your temporary stuff it gets allocated on memory pools which are deleted per-frame, per-scene etc.
added on the 2010-08-01 10:34:25 by _-_-__ _-_-__
duffman: What rasmus said. If you're size-coding so hard that you care about the overhead of virtual methods, you probably shouldn't be desiging class hierarchies to begin with.
added on the 2010-08-01 10:50:12 by doomdoom doomdoom
Quote:
Valgrind? Is that what Linux programmers do instead of having a HTTP server that shows live memory usage sorted by all kinds of criteria while the program is running at normal speed?


That is a pretty ossom idea! Do you use custom allocators to supply a name or properties to each memory block?
added on the 2010-08-01 12:17:47 by trc_wm trc_wm
I thought we did those things via a python client showing all sorts of graphs about memory usage by category (geometry, texture etc) and FPS split into various areas.
added on the 2010-08-01 12:46:25 by _-_-__ _-_-__
all ur base destructors r belong 2 me. there..that solves it.
added on the 2010-08-01 13:53:27 by xrs xrs
Quote:
Exactly. The OS is your perfect deallocator.

Maybe he's coding for Amiga.
added on the 2010-08-01 15:18:05 by Gargaj Gargaj
Quote:

Valgrind? Is that what Linux programmers do instead of having a HTTP server that shows live memory usage sorted by all kinds of criteria while the program is running at normal speed?


The real question is what we Linux guys do in our free-time while you Windows guys hunt down thread synchronization bugs...

valgrind --tool=helgrind anyone?

added on the 2010-08-01 16:16:08 by torus torus

login