# V554. Incorrect use of smart pointer.

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

Рассмотрим первый пример:

    void Foo()
    {
      struct A
      {
        A() { cout << "A()" << endl; }
        ~A() { cout << "~A()" << endl; }
      };

      std::unique_ptr<A> p(new A[3]);
    }

По умолчанию класс unique_ptr использует для освобождения памяти оператор 'delete'. Поэтому будет разрушен только один объект класса 'A' и на экране будет распечатан следующий текст:

    A()
    A()
    A()
    ~A()

Чтобы исправить ошибку необходимо указать, что необходимо использовать оператор 'delete []'. Корректный вариант кода:

    std::unique_ptr<A[]> p(new A[3]);

Теперь будет вызываться равное количество конструкторов и деструкторов и будет распечатан текст:

    A()
    A()
    A()
    ~A()
    ~A()
    ~A()

Рассмотрим второй пример:

    std::unique_ptr<int []> p((int *)malloc(sizeof(int) * 5));

Память выделяется с использованием функции 'malloc()', а освобождается при помощи оператора 'delete []'. Это некорректно и следует указать, что освобождать память надо используя функцию 'free()'. Корректный вариант кода может выглядеть следующим образом:

    int *d =(int *)std::malloc(sizeof(int) * 5);
    unique_ptr<int, void (*)(void*)> p(d, std::free);

Дополнительные материалы по данной теме:

- Обсуждение на сайте Stack Overflow. "How could pairing new[] with delete possibly lead to memory leak only?".

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки управления динамической памятью (выделения, освобождения, использования освобожденной памяти) [* см. примечание касательно языков C#, Java].

Данная диагностика классифицируется как:

CWE-762 CERT-MEM51-CPP

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