﻿# V1023\. A pointer without owner is added to the container by the 'emplace\_back' method\. A memory leak will occur in case of an exception\.

Анализатор обнаружил код добавления в контейнер умных указателей с помощью 'emplace\_back\(new X\)'\. Этот код может привести к утечке памяти\. 

Пример:

```cpp
std::vector<std::unique_ptr<int>> pointers;
pointers.emplace_back(new int(42));
```

В случае, если вектору понадобится реаллокация и он не сможет выделить память под новый массив, то он бросит исключение и указатель будет потерян\.

Корректный код:

```cpp
pointers.push_back(std::unique_ptr<int>(new int(42)));
pointers.push_back(std::make_unique<int>(42));
```

Давайте разберёмся с этим видом ошибки более подробно\.

Для добавлении элемента в конец контейнера типа 'std::vector<std::unique\_ptr<X\>\>' нельзя просто написать 'v\.push\_back\(new X\)', так как нет неявного преобразования из 'X\*' в 'std::unique\_ptr<X\>'\.

Распространенным решением является написание 'v\.emplace\_back\(new X\)', так как он компилируется: метод 'emplace\_back' конструирует элемент непосредственно из аргументов и поэтому может использовать явные конструкторы\. 

Тем не менее, это не безопасно\. Если вектор полон, то происходит перевыделение памяти\. Операция перевыделения памяти может закончиться неудачей, в результате чего будет сгенерировано исключение 'std::bad\_alloc'\. В этом случае указатель будет потерян, и созданный объект никогда не будет удален\.

Безопасным решением является создание 'unique\_ptr', который будет владеть указателем до того, как вектор попытается перевыделить память:

```cpp
v.push_back(std::unique_ptr<X>(new X))
```

Начиная с C\+\+14 можно использовать 'std::make\_unique':

```cpp
v.push_back(std::make_unique<X>())
```