Reputation: 426
In the following code, when ptr
is deleted, the destructor for Base
is called, but not the destructor for Derived
(due to destructor of Base
not being virtual).
class Base
{
int b;
};
class Derived : public Base
{
int d;
};
int main(void)
{
Base * ptr = new Derived();
delete ptr;
return 0;
}
Valgrind reports that the program contains no memory leaks, which i guess is true in the sense that all newed data is deleted in this particular case. My question is - given that the (default) destructor of Derived
is not called, when and how is the memory for d
deallocated or reclaimed?
Upvotes: 6
Views: 308
Reputation: 2594
As other great guys mentioned, the standard says it is undefined behavior, but usually amongst compilers that care about competition and users this is up to system allocator implementation, which can be different from platform to platform. The destructor itself does not free the memory of Derived
object, which contains fields.
When you call new Derived
, global implementation of operator new
is called and it receives number of bytes to allocate. It will be sizeof(Derived)
in your case.
Upon actual memory freeing (global operator delete
), allocator will know how many bytes to free from the address of the object being freed. So, the memory used by both b
and d
will be reclaimed
Upvotes: 1
Reputation: 129524
Calling the incorrect destructor, I think, is undefined behaviour. You should have a virtual destructor.
However, since the allocation is done in one block for the Derived class, it "works" because the internals of delete simply keeps track of the size of the allocation, and thus frees the 8 bytes that the object takes up, instead of the four that Base would use.
Note that the virtual destructor is not responsible in itself of FREEING the memory that this
points to. That happens in delete
after the destructor has been called.
Upvotes: 2
Reputation: 206646
It is Undefined behavior to call delete
on a base class pointer pointing to a derived class object if the destructor in base class is not virtual
.
Undefined behavior means that anything can happen. Whether memory leaks or not is irrelevant the fact is that your program can show any behavior and you cannot rely on any behavior that is shown.
For your code to be valid the destructor in Base class must be virtual
.
C++11 Standard 5.3.5 Delete:
Para 3:
In the first alternative (delete object), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
Upvotes: 8