Ответ 1
A std::nothrow_t
существует функция освобождения, но вы не можете вызвать ее с выражением delete
.
Функция дезадаптации существует для полноты. Если выражение new
терпит неудачу из-за исключения, компилятор должен освободить выделенную память через operator new
с помощью соответствия на operator delete
. Таким образом, должен быть operator delete
, который принимает std::nothrow_t
, чтобы это разрешить.
(То есть, в общем случае выражение new
с формой new (args...) T
будет выделять память с вызовом operator new(sizeof(T), args...)
. To "match" означает вызов operator delete
с теми же аргументами, кроме первого.)
Обратите внимание, что вы можете напрямую вызвать оператора: operator delete(memory, std::nothrow);
. Однако выражение delete
никогда не вызывает глобальную функцию освобождения с дополнительными параметрами.
Итак, вы можете "вызвать" его с помощью:
struct always_throw
{
always_throw() { throw std::exception(); }
};
new (std::nothrow) always_throw;
В какой-то момент это распределит память с вызовом:
void* __memory = operator new(sizeof(always_throw), std::nothrow);
Поскольку инициализация объекта бросает, компилятор должен освободить выделенную память с помощью соответствующей функции освобождения, поэтому он выполняет следующие действия:
operator delete(__memory, std::nothrow);
Вызов версии std::nothrow_t
.