Использование std :: destroy_at () в C ++ 17? - PullRequest
0 голосов
/ 26 сентября 2018

У меня есть простой фрагмент кода, который пытается освободить память с помощью std::destroy_at():

#include <iostream>
#include <memory>

using namespace std;

class base
{
public:
  ~base()
  {
    cout << "des" << endl;
  }
};
int main()
{
  {
    base* b1 = new base();
    std::destroy_at(b1); // destructor is executed for b1 object (but memory is not freed for b1)
  }
return 0;
}

Может кто-нибудь подсказать мне, как использовать destroy_at() для освобождения памяти?Такое же поведение наблюдается и для примитивных типов данных.Последняя версия компилятора VS2017.

1 Ответ

0 голосов
/ 26 сентября 2018

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].Такие альтернативные модели распределителей распространены в критически важных приложениях.
....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...