Search code examples
c++operator-overloadingdynamic-memory-allocationnew-operatordelete-operator

Getting issue with placement new and delete operator


I have written the following code for placement new and delete operator functions. Can you please tell the issue with the code below.

// new_operator.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
using namespace std;
class Mem
{
public:
    void* alloc(size_t sz) { return malloc(sz); }
    void dealloc(void* ptr) { free(ptr); }
};

class Object
{
public:
    Object() { cout << "In Constructor Object()" << this << endl; }
    ~Object() { cout << "In Destuctor ~Object()" << endl; }
    void* operator new(size_t sz, Mem* handle)
    {
        Object* x1 = (Object*)handle->alloc(sz);
        return x1;
    }
    void operator delete(void* ptr, Mem* handle)
    {
        cout << "Here\n";
        ((Object*)(ptr))->~Object();
        handle->dealloc(ptr);
    }
};
int main()
{
    Mem* memory = new Mem;
    Object* obj = new (memory) Object;
    cout << "Obj is " << obj << endl;
    delete (obj, memory);
    delete memory;
    return 0;
}

I'm getting runtime crashes at the time when delete operator function starts executing. Can anyone please tell what I'm doing wrong.


Solution

    1. Placement delete is called to free memory when a constructor called from placement new fails. You are not supposed to call any destructors from any version of operator delete, because operator delete frees memory that is left after an object that used to reside there is destroyed (or was never constructed to begin with).
    2. The only way to explicitly call a placement operator delete is to spell out two words operator delete, thus making a function-call-expression. You cannot invoke it from a delete-expression (there is no placement-delete-expression syntax). In your case, you would need to use a qualified name: Object::operator delete. Note that if you remove the explicit destructor call from Object::operator delete, as you should because of the above, the destructor will not be called. There is no way to both invoke the destructor and free the memory in a single call to a placement delete. The easiest way to handle this is to create and use a non-static member function, say void Object::destroy(Mem*).