память об ошибках c Klocwork выделяется через вызов ‘new[]’

#c #memory #klocwork

#c #память #klocwork

Вопрос:

Klocwork 2020.1 Сборка 20.1.0.97

 // Vertices of simplex
auto v = new double*[n   1]; // this line give the error
// Average coordinates
auto v_ave = new double[n];
// Reflection coordinates
auto v_ref = new double[n];
// Expansion coordinates
auto v_exp = new double[n];
// Contraction coordinates
auto v_con = new double[n];

 if (v == nullptr || v_ave == nullptr || v_ref == nullptr || v_exp == nullptr || v_con == nullptr)
 {
     status = false;
     goto free_mem;
  }

    // Allocate the columns of the arrays
    for (int idx = 0; idx <= n; idx  )
    {
        v[idx] = new double[n];
        if (v[idx] == nullptr)
        {
           status = false;
           goto free_mem;
        }
    }
 

….
вот как освобождается память

 free_mem:
    if (v != nullptr)
    {
        // Free memory
        for (int idx = 0; idx <= n; idx  )
        {
            delete[] v[idx];
        }
        delete[] v;
    }

    delete[] v_ave;
    delete[] v_ref;
    delete[] v_con;
    delete[] v_exp;

    return pair<double, bool>(min, status);
 

это ошибка KW, которую вы получаете
введите описание изображения здесь

Я не понимаю проблемы и не могу найти никаких предложений по ее устранению.

Комментарии:

1. Для любого вида «динамического массива» правильное решение почти всегда std::vector .

2. @Someprogrammerdude вы совершенно правы. но это не мой код, и я хочу просто разблокировать эту проблему KW.

3. @Someprogrammerdude Проверка необходима. delete[] v[idx]; будет UB, если v равно null.

4. Ну, использование вектора — это действительно «правильное» исправление. Если вы просто не хотите отключить ошибку (что обычно возможно с помощью статических анализаторов, но если вы делаете это глобально, вы можете пропустить места, где эта ошибка оправдана).

5. Ваш код, как показано, инициализируется v с помощью new double*[n 1] , и не инициализирует какие-либо элементы v . Код освобождения освобождает (используя delete[] ) каждый элемент v , а затем v сам. Таким образом, освобождение не соответствует распределению. Кроме того, при освобождении v нет необходимости проверять, является ли v (или любой из других указателей) nullptr , поскольку по умолчанию new[] выражение генерирует исключение вместо указания значения nullptr .

Ответ №1:

память выделяется с помощью вызова команды ‘new[]’.

Я не могу найти никаких предложений по исправлению ситуации.

Исправить ошибку «память выделяется через вызов new[]» — значит не выделять память через new[]. Самое простое решение — использовать std::vector вместо этого.

Комментарии:

1. @eeroika Я не могу изменить тип v.

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

3. вы имеете в виду vector-> data ()? проблема в том, что позже код использует v во многих других местах и переходит к другим функциям. итак, чтобы изменить тип, мне нужно потратить 2 дня. которого у меня сейчас нет.

4. @Gilad Да, data дал бы вам этот указатель. Я не понимаю, как v использование может быть проблемой. В любом случае, именно так ошибка может быть исправлена. То, что для исправления требуется слишком много времени, этого не меняет.

5. std::vector<double*> real_v(n 1); auto v = real_v.data(); ? У вас все так v же, как и раньше, и с тем же типом. Это не идеальное решение, поскольку то, что действительно должен иметь код std::vector<std::vector<double>> .