Reputation: 5194
I'm overloading operator new/delete in a subclass, and I'm noticing a behaviour that seems rather odd to me. Take a look at the sample code below:
#include <stdlib.h>
#include <stdio.h>
class Base
{
public:
virtual ~Base()
{
}
};
class Derived : public Base
{
public:
void* operator new(unsigned int size, int capacity)
{
printf("> new(unsigned int, int)\n");
return malloc(sizeof(Derived));
}
void operator delete(void* ptr, int)
{
printf("> delete(void*, int)\n");
free(ptr);
}
void operator delete(void* ptr)
{
printf("> delete(void*)\n");
free(ptr);
}
};
int main(int argc, char** argv)
{
Base* base = new (0) Derived();
delete base;
return 0;
}
This code generates the following output when compiled with Visual Studio 2010:
> new(unsigned int, int)
> delete(void*)
Why is the matching delete operator (Derived::operator delete(void*, int)
) not getting called here? No matter what I do, I cannot get the code to call the matching operator delete.
Upvotes: 2
Views: 1252
Reputation: 476970
The fundamental mantra:
There is no placement-delete expression.
If you use placement-new to create an object, you must destroy it manually and then invoke the deallocation function:
Base * p = new (0) Derived;
p->~Derived();
Derived::operator delete(p, 0);
If you will, it is sort of undefined behaviour to say delete base;
in your code because you never obtained base
as the result of a standard new-expression. It's entirely possible that you defined a placement-new allocation function that does something entirely different, and calling the standard operator delete
-deallocation function might wreak total havoc. It just so happens that in your program it works out.
Upvotes: 5