::operator new in the global namespace can be replaced (redefined) rather than overloaded. This causes the override to be used instead of the function provided by the standard library. And my_class::operator new can be provided, so it will be used in new my_class expressions, which is also different from overloading.
The new overload is only enabled when using the new placement syntax:
new ( memory_pool, 123, other_args ) my_class( constructor_args )
Providing additional arguments to parens after the new keyword causes another operator new overload to be called, with additional arguments added after size_t to determine how much memory is required.
You can overload ::malloc just like any other function by defining a version that takes different arguments:
void *malloc( std::size_t size, allocation_pool &pool );
This is just a new feature called malloc . But it is better to name library functions with an explicit qualification std:: , and adding an overload of std::malloc will violate the rules of the library.
You cannot replace std::malloc . The only functions that can be replaced are the standard options ::operator new . There is no such thing as a class-specific malloc , because it does not accept an argument indicating which class will go into the returned memory block. malloc does not know what you will do with the returned memory; it's just a drop of bytes.
In connection with the organization of the program, a more specialized distributor should probably be defined and called as a different name, not malloc . If you need to call different functions depending on the type, use a template like
template< typename allocated > void *my_allocate( std::size_t sz );
You can also specialize std::allocator< my_class > and its allocate member allocate . Then the various standard libraries will call your function, despite the lack of the new setting. (Perhaps you will avoid embedding it too deeply into custom new because of your quirks.)