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)'. Этот код может привести к утечке памяти.

Пример:

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

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

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

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', который будет владеть указателем до того, как вектор попытается перевыделить память:

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

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

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

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-460.

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V1023.


Найденные ошибки

Проверено проектов
346
Собрано ошибок
13 188

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;