32

Suppose I need to overload global ::operator new() for storing extra data with each allocated object. So basically it would work this way:

  • for each call to global ::operator new() it will take the object size passed and add the size of extra data
  • it will allocate a memory block of size deduced at previous step
  • it will offset the pointer to the part of the block not occupied with extra data and return that offset value to the caller

::operator delete() will do the same in reverse - shift the pointer, access extra data, deallocate memory.

Now the question is how do I allocate memory? Of course I can call malloc() or some platform-specific function (that's how it is usually done). But normally when I need to allocate raw memory in C++ I call ::operator new(). Can I call the original ::operator new() to do the memory allocation from inside my overloaded global ::operator new()?

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 8
    Do you mean overloaded or replaced? If overloaded, just call the original operator new by using the correct set of arguments. If replaced, then no you can't but I believe this is _why_ `malloc` is guaranteed not to use `operator new` in its implementation (i.e. no unintentional loops when operator new is replaced) so you probably should be using `malloc`. – CB Bailey Nov 09 '10 at 13:41
  • 2
    @CharlesBailey You wrote your answer as a comment! for shame! – lmat - Reinstate Monica Feb 12 '14 at 16:57

1 Answers1

23

You can't access them because it isn't really overloading, it's replacement. When you define your own ::operator new, the old one goes away. That's pretty much that.

Essentially, you need to call malloc from a custom ::operator new. Not only that, but also follow the directions in 18.4.1.1/4 to properly handle errors:

Default behavior:

— Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified.

— Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, throw bad_alloc.

— Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats.

— The loop terminates when an attempt to allocate the requested storage is successful or when a called new_handler function does not return.

Community
  • 1
  • 1
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 1
    And don't forget to replace `operator delete` too, with `free()`. – wilhelmtell Nov 09 '10 at 13:56
  • I believe Scott Meyers talks about this in detail in on of his _Effective C++_ books. Item 8 in the second edition, and chapter 8 in the 3rd, as it seems. – wilhelmtell Nov 09 '10 at 14:01
  • @Potatoswatter: Couldn't he use `malloc()` to allocate the memory for his class and extra data and then call `placement-new` to instantiate the class object within this memory. Since he's only replacing the regular version of `new` wouldn't the default `placement-new` be called? – Praetorian Nov 09 '10 at 14:03
  • @Praetorian: That will work, but this will force me to handle all error handling myself. For example - what if the constructor throws? – sharptooth Nov 09 '10 at 14:10
  • 1
    @Sharptooth: You can have everything in a `try-catch` block, cleanup the allocated memory and rethrow the exception. – Praetorian Nov 09 '10 at 14:14
  • @sharptooth: Why do you think that you need to worry about the constructor throwing? If you replace `operator new` and `operator delete` the implementation will ensure that your replaced `operator delete` will be called if the constructor of an object throws after you've successfully returned a pointer to allocated memory for the object from your replaced `operator new`. – CB Bailey Nov 09 '10 at 14:18
  • @Charles Bailey: Yes, sure, but only if I use a new-statement. User Praetorian seems to suggest that I allocate memory and then call the constructor in-place (via placement new). In this case C++ won't take care of memory deallocation. – sharptooth Nov 09 '10 at 14:21
  • @sharptooth: OK, I looks like I didn't fully understand what Praetorian was suggesting. – CB Bailey Nov 09 '10 at 15:06