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.
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.
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.
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.
Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With