Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

overriding delete with parameters

Tags:

c++

I can override global operator new with different parameters, so for example I can have:

void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, int num) throw (std::bad_alloc);

which can be called separately as

int* p1 = new int; // calls new(size_t)
int* p2 = new(5) int; // calls new(size_t, int)

since each of these can potentially use some different allocation scheme, I would need a separate delete() function for each. However, delete(void*) cannot be overloaded in the same way! delete(void*) is the only valid signature. So how can the above case be handled?

P.S. I am not suggesting this is a good idea. This kind of thing happened to me and so I discovered this "flaw" (at least in my opinion) in c++. If the language allows the new overrides, it must allow the delete overrides, or it becomes useless. And so I was wondering if there is a way around this, not if this a good idea.

like image 519
Baruch Avatar asked Jul 11 '12 11:07

Baruch


People also ask

What does Delete () do in C++?

Using the delete operator on an object deallocates its memory. A program that dereferences a pointer after the object is deleted can have unpredictable results or crash.

When to use delete [] and delete?

Using delete will only delete one single object. In the code above, we have an array of objects, thus the right way to delete those objects is by using delete []. So when you have a single object you use delete. When you have an array of objects you need to use delete[] as shown in the example below.

Can delete operator be overloaded?

New and Delete operators can be overloaded globally or they can be overloaded for specific classes. If these operators are overloaded using member function for a class, it means that these operators are overloaded only for that specific class.

Can you use Delete on an array?

Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression.


1 Answers

I can override global operator new with different parameters

Those are called placement allocation functions.

delete(void*) is the only valid signature.

No.

First, some terminology: A delete expression such as delete p is not just a function call, it invokes the destructor then calls a deallocation function, which is some overload of operator delete that is chosen by overload resolution.

You can override operator delete with signatures to match your placement allocation function, but that overload will only be used if the constructor called by the placement new expression throws an exception e.g.

struct E {
    E() { throw 1; }
};

void* operator new(std::size_t n, int) throw(std::bad_alloc) { return new char[n]; }
void operator delete(void* p, int)  { std::puts("hello!"); delete[] (char*)p; }

int main()
{
    try {
        new (1) E;
    } catch (...) {
        puts("caught");
    }
}

The placement deallocation function which matches the form of placement new expression used (in this case it has an int parameter) is found by overload resolution and called to deallocate the storage.

So you can provide "placement delete" functions, you just can't call them explicitly. It's up to you to remember how you allocated an object and ensure you use the corresponding deallocation.

like image 194
Jonathan Wakely Avatar answered Sep 24 '22 02:09

Jonathan Wakely