Hi everyone! I've been reading many an article on this matter, but I want to make sure I've understood everything correctly. The thing is, that I couldn't find any source that explicitly "validated" what I plan to do in my specific case, so I though I'd ask more experienced people than me.

I want to replace global operators new and delete. There are two reasons I want to do this, and to each of them corresponds a "step" I want to be sure of:

1) I want to do some simple tracking of my allocations; keeping a record of how much memory I allocated in the heap, and who allocated it, should help me in spotting memory leaks;

2) I may want to do in the future some sort of custom memory allocation. While I know this is usually a form of optimization, and it's wrong to optimize early in the project, I would like to create something which will allow me to drop in a custom allocator without too much hassle.

From what I've got, point 1 is very easy to achieve. Basically I only need to define an overload of the global new with additional parameters, like:
Code:
 void* operator new(size_t size, const char* file, const char* function /*, more parameters as needed */)
Of course, I'll have to define a symmetric delete operator that takes the same arguments, to avoid leaks should the constructor throw an exception. Question #1: if I don't use exceptions in my code, do I still have to define this delete overload? Do I need to worry about the nothrow overloads, or is it safe to ignore them?

At first I wondered what would happen if I also replaced the default delete definition (the delete(void* ptr) one). Let's suppose my new/delete overloads use malloc()/free(); the objects I create will be created with malloc() and deleted with free(), but the objects that third-party code would create (with the "regular" new operator) would be deleted with free(), but I could not be sure whether they were created with malloc(). This, of course, would be bad.

Then I figured that my overloads of new and delete could, in fact, simply call the regular new and delete after they did their record-keeping stuff. This way, all of the objects (both mine and third-parties') would be created with the allocator used by the C++ implementation, and deleted with the very same allocator. I've read articles that confirm this idea; is this correct (question #2)? I have to ask because it's hard for me to write a test for this kind of problems; maybe I'm just being lucky and using by chance the same allocator my compiler uses; maybe I just didn't make a test valid enough to observe bad behaviour when I do something wrong.

The second reason why I need to fiddle with new and delete seems to be way trickier. From what I've got, to implement a custom allocator I would be better off splitting the two operations performed by new. So, in my "step 2" overload of new there would be
a) the record-keeping stuff
b) allocation of memory by the allocator - something like
Code:
void* pObject = MemoryAllocator::Allocate(size);
c) construction of the object via non-overloaded placement new

Symmetrically, my "step 2" delete would feature
a) the record-keeping stuff
b) destruction of the object with an explicit call of the destructor method
c) deallocation of the memory pointed to: MemoryAllocator::Free(ptr)

Question #3: is it correct that I have to use operator new placement with a custom allocator? As far as I know, I can't pass an allocator object to new. What I am confused about, is: how would I know the class of the object to construct? The same applies for the destructor.

Question #4: would it be a better choice to leave the new/delete operators as they were in step 1 (i.e., with the call to the regular operators), and to proceed to override them on a class basis, so that I can define a base class for all the objects that will need a particular allocator (say, class PooledObject, which all objects that need to be pooled will derive from), while leaving the rest of the allocations untouched?

Also, marginally, question #5: should the record-keeping code go before or after the construction/destruction of the object? Of course it's wise to not separate allocation from construction (and destruction from deallocation). I guess it would be better to do the construction first, and then the record-keeping, so that the construction is not recorded if something goes wrong (exceptions); symmetrically, destroy the record (if it exists) then destroy the object. Am I correct?

Thanks a lot for the patience to read all of this! :-)