std::destroy_at()
не предназначен для освобождения памяти в соответствии с [special.destroy] p1 он предназначен для вызова деструктора объекта:
шаблон
void destroy_at (T * location);
1. Эффекты: Эквивалентно:
location->~T();
Запись cppreference дает пример того, почему это может бытьнеобходимо.В этом случае мы использовали размещение нового в буфер, и нет необходимости освобождать память:
struct Tracer {
int value;
~Tracer() { std::cout << value << " destructed\n"; }
};
int main()
{
alignas(Tracer) unsigned char buffer[sizeof(Tracer) * 8];
for (int i = 0; i < 8; ++i)
new(buffer + sizeof(Tracer) * i) Tracer{i}; //manually construct objects
auto ptr = std::launder(reinterpret_cast<Tracer*>(buffer));
for (int i = 0; i < 8; ++i)
std::destroy_at(ptr + i);
}
Предложение, которое привело к этому Расширение инструментов управления памятью гласит:
Как для стандартной библиотеки, так и для пользовательских библиотек обычно управляют памятью без использования совместимых со стандартами распределителей .Они могут использовать внутренние буферы (например, необязательно) или использовать модель распределителя, которая не управляет временем жизни объекта [bde] [sgi] [eastl] [bitquid].Такие альтернативные модели распределителей распространены в критически важных приложениях.
....