Для чего нужен второй параметр у оператора operator delete?
1,00
р.
р.
Есть ли разница в объявлении operator delete(void*) и operator delete(void*, size_t) для класса? Нужен ли на самом деле второй параметр? И если да, то зачем?
Ответ Наличие второго опционального параметра типа size_t в функции operator delete тянется еще со времен "классического" C++, т.е. C++98, где такой параметр мог использоваться в operator delete, перегруженных именно для индивидуальных классов. То есть внутри конкретного класса вы можете на выбор объявлять operator delete(void *p) // или operator delete(void *p, size_t s) В ситуации, когда удаляемый класс предоставляет свой собственный перегруженный operator delete со вторым параметром типа size_t, компилятор обязан передать в такой оператор корректный размер удаляемого блока памяти, т.е. тот же размер, что передавался в operator new при выделении этого блока. Для глобального operator delete такой возможности не предоставлялось. Эта возможность предусмотрена в языке из-за того, что перегруженные operator new и operator delete базового класса могут использоваться для выделения/освобождения памяти для объектов производных классов struct Base { void *operator new(size_t s) { std::cout << "new " << s << std::endl return ::operator new(s) }<br> void operator delete(void *p, size_t s) { std::cout << "delete " << s << std::endl ::operator delete(p) } } <br>struct Derived : Base { char buffer[1024] } int main() { Base *pb = new Base delete pb Derived *pd = new Derived delete pd } При помощи анализа передаваемого в operator new и operator delete значения эти операторы могут определять, какой из возможных размеров выделяется или освобождается и соответствующим образом перенаправлять вызовы. Для глобальных функций ::operator new и ::operator delete такой возможности в C++98 не было, т.е. глобально предоставлялся только замещаемый operator delete(void *p) Однако начиная с С++14 такая возможность была предоставлена и для глобальных функций тоже. Это было сделано для улучшения поддержки аллокаторов, которые не хранят размер блока в самом блоке (или где-то рядом), т.е. для аллокаторов которым трудно определить размер блока по указателю. Например, для пулов одноразмерных объектов. Также такая возможность может быть полезна для оптимизации выделения/освобождения памяти в появившейся в C++14 возможности расширенных выделений памяти, когда два или более соседних new-выражения обходятся одним вызовом operator new с суммарным размером (и, соответственно, симметричной обработкой delete-выражений). То есть если вы по какой-то причине хотите получать в ::operator delete тот же самый размер, что передавался в соответствующий вызов ::operator new, то объявляйте свой ::operator delete со вторым параметром типа size_t. Если вас не интересует этот размер, то объявляйте его без такого параметра.
Ситуация с наличием сразу двух вариантов operator delete, похоже, находится в подвешенном состоянии уже давно и является дефектом стандарта. Скорее всего дело закончится тем, что предоставление сразу двух вариантов будет приводить к ошибке неоднозначности.