ProgrammingC++ developer, systems programmer

Tell us about the operator new/operator delete mechanism in C++. How do they differ from new/delete, when and why are operator functions overloaded in user-defined classes?

Pass interviews with Hintsage AI assistant

Answer.

In C++, operator new and operator delete are memory allocation and deallocation functions invoked when creating and destroying objects using the new and delete operators. By default, they use the standard allocator, but they can be overloaded in a class for finer control over memory management.

  • operator new allocates a "raw" block of memory without calling the constructor.
  • After memory allocation, the object's constructor is automatically called.
  • operator delete frees the memory after the object's destructor has finished.

Usage (global and local versions):

  • The global version is used by default (e.g., when using new int).
  • By overriding a specific operator new in the class, memory management can be optimized for objects of that class (e.g., object pools, tracing, block reuse).

Example of overloading operator new/operator delete:

#include <iostream> class TrackAlloc { public: void* operator new(size_t size) { std::cout << "TrackAlloc::new for " << size << " bytes "; return ::operator new(size); } void operator delete(void* ptr) { std::cout << "TrackAlloc::delete "; ::operator delete(ptr); } };

Nuances:

  • Calling new/deleting objects with arguments (placement new) requires a separate overload.
  • Overloaded operators are only called when creating/deleting objects of the class, not for new[]/delete[]. Separate operator new[]/delete[] can be overloaded for them.
  • Memory manipulation is dangerous — proper exception handling is required.

Trick question.

"What happens if you overload the new operator in a class and then create an object through a derived class variable? Which version of operator new will be called?"

Answer: The operator new of the class from which the object is created will be invoked. If the derived class does not implement operator new, the compiler will attempt to find a suitable version in the base class or the global version.

Example:

struct Base { void* operator new(size_t s) { std::cout << "Base new "; return ::operator new(s); } }; struct Derived : Base {}; Derived* p = new Derived; // Will call Base::operator new!

Examples of real errors due to ignorance of the topic nuances.


History

Developers overloaded operator new/ delete without supporting proper exception handling. When an exception was thrown inside the constructor, memory was not released, leading to leaks.


History

Incorrectly implemented operator new[] and operator delete[]: for the class that contained arrays, the new implementation was not called — the default versions were used, leading to desynchronization of memory allocation and deallocation logic.


History

Overloading the global operator new affected the operation of third-party libraries: all objects (including temporary ones and from STL) began to be allocated through the logged allocator, which critically slowed down the application's core.