Is it possible to put some restrictions in overloading operators new and delete?
My overloaded new is linked in a different file to my test program.
The scenario is:
if(condition is satisfied)
call overloaded new
else
call the actual new defined in new.h
There are three ways to provide an operator new.
replacing one or more of the four non placement default operators new,
providing overload to the default operator new (thus with an additional parameter, those may be called with the placement new syntax),
providing operator new class members, those will be called only for that class and their descendant.
In the latter two cases, it is possible to call one of the more well know operators new with the syntax:
ptr = ::operator new(sz);
ptr = ::operator new[](sz);
ptr = ::operator new(sz, std::nothrow);
ptr = ::operator new[](sz, std::nothrow);
but if you have replaced them, your replacement will be called. You can't call the default operators new you have replaced (well perhaps you can by playing implementation specific linker tricks, but that's outside the scope of the language).
About the replacement of operator new:
- you should replace the two operators new and the corresponding two operator delete together (or one of the delete operator could be easily called with unexpected pointer)
- you should replace the two operators new[] and the corresponding two operator delete[] together (same reason)
- pay attention to what is possible with the new handlers, some library plays with that.
Always use your overloaded new
/delete
and check your condition inside its implementation.
Once you replace the default ::operator new()
you can't use it anymore - it's gone forever. See this question.
If you want to have the effect of the original ::operator new()
you'll have to reimplement it which isn't very hard.
You can easily perform the check in your overloaded new operator. Be sure to implement all flavours of the new operator (as AProgrammer already pointed out).
Calling the original/default new is not possible, but it's not difficult to implement it yourself. After all, new only allocates memory, that's it. So instead of calling the original/default new, you can also call malloc, HeapAlloc, or any memory-allocation routine found on your system. Be sure to call the corresponding memory-deallocation method (free, HeapFree, ...) in your implementation of delete.
You didn't tell what kind of condition you are going to check in your implementation of new? If it's a 'static' condition (I mean: always giving the same result during the execution of your application), the same condition should also be added to your implementation of delete.
If the condition depends on the situation and changes while running your application, you should foresee a method where you can know which delete implementation to use in your delete function. One trick do to this is the following:
In your implementation of new:
- allocate 8 bytes more than requested (this must be 8 bytes to keep the alignment correct)
- fill in the first 8 bytes with an identification so that you can know which underlying memory-allocation function you used
- add 8 bytes to the allocated pointer and return this one
In your implementation of delete:
- subtract 8 bytes of the pointer given to you
- check the identification found at that place (see new) to see which kind of underlying delete-implementation you should call