Zeenobit
Zeenobit

Reputation: 5194

Overloaded operator new and matching delete

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

Answers (1)

Kerrek SB
Kerrek SB

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

Related Questions