c++ – What is the second parameter of the operator delete operator for?

Question:

Is there a difference in the declaration of operator delete(void*) and operator delete(void*, size_t) for a class? Is the second parameter really needed? And if so, why?

Answer:

The presence of the second optional parameter of type size_t in the operator delete function has been going on since the days of the "classic" C ++, i.e. C++98, where such a parameter could be used in operator delete overloaded specifically for individual . That is, inside a particular class, you can choose to declare

operator delete(void *p);
// или 
operator delete(void *p, size_t s);

In a situation where the class being deleted provides its own overloaded operator delete with a second parameter of type size_t , the compiler must pass the correct size of the memory block to be deleted to such an operator, i.e. the same size that was passed to operator new when this block was allocated.

For the global operator delete , this was not provided.

This possibility is provided in the language due to the fact that the overloaded operator new and operator delete of the base class can be used to allocate / deallocate memory for objects of derived classes.

struct Base
{
  void *operator new(size_t s) 
  { 
    std::cout << "new " << s << std::endl;
    return ::operator new(s); 
  }

  void operator delete(void *p, size_t s) 
  { 
    std::cout << "delete " << s << std::endl;
    ::operator delete(p);
  }
};

struct Derived : Base
{
  char buffer[1024];
};

int main()
{
  Base *pb = new Base;
  delete pb;

  Derived *pd = new Derived;
  delete pd;
}

By parsing the values ​​passed to operator new and operator delete , these operators can determine which of the possible sizes is allocated or deallocated and redirect calls accordingly.

For the global functions ::operator new and ::operator delete there was no such possibility in C++98; only the replacement was provided globally

operator delete(void *p);

However, since C++14, this possibility has been provided for global functions too. This was done to improve support for allocators that do not store the block size in the block itself (or somewhere nearby), i.e. for allocators for which it is difficult to determine the block size from the pointer. For example, for pools of one-dimensional objects. Also, this feature can be useful for optimizing memory allocation / deallocation in the possibility of extended memory allocations that appeared in C ++ 14, when two or more neighboring new expressions are managed by one operator new call with a total size (and, accordingly, symmetrical processing of delete expressions ).

That is, if for some reason you want to receive the same size in ::operator delete as was passed in the corresponding call to ::operator new , then declare your ::operator delete with a second parameter of type size_t . If you are not interested in this size, then declare it without such a parameter.


The situation with the presence of two variants of operator delete at once seems to have been in limbo for a long time and isa defect in the standard . Most likely, the case will end up with the fact that providing two options at once will lead to an ambiguity error.

Scroll to Top