PVS-Studio для проверки лабораторных работ на C и C++

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

C++ error: "pointer being freed was not allocated


Встретил очередной вопрос на Stack Overflow от человека, изучающего язык C++. Количество подобных вопросов можно сократить, используя PVS-Studio. Человек сразу может получить ответ, не отвлекая других.


Я уже описывал здесь, что online версия анализатора PVS-Studio может существенно облегчить жизнь начинающим программистам. Рассмотрим ещё один подобный случай.


Заглянем в дискуссию "C++ error: "pointer being freed was not allocated" на сайте Stack Overflow и посмотрим на этот код:


#include <stdexcept>
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>

using std::cout;
using std::endl;
using std::vector;      

typedef vector<int> ints;

void print_ints(vector<int>);
void print_ints_vec(vector<vector<int>>);
void int_part(int, vector<vector<int>>&);

int main() 
{
  vector<vector<int>> partition;
  int_part(5, partition);
  print_ints_vec(partition);

  return 0;
}

void int_part(int sum, vector<vector<int>>& res)
{
  vector<int> init_xs = vector<int>{sum};
  vector<int>* xs = &init_xs; // POINTER INITIALIZED TO vector<int>
  int current_sum = sum;

  while (true) 
  {
    current_sum = accumulate(xs->begin(), xs->end(), 0);

    if (current_sum == sum)
    {
      res.push_back(*xs);
      vector<int> next_xs;
      vector<int>::iterator it = find(xs->begin(), xs->end(), 1);
      if (it == xs->begin()) return;
      copy(xs->begin(), it, back_inserter(next_xs));
      next_xs[next_xs.size() - 1] -= 1;
      xs = &next_xs; // POINTER REASSIGNED TO ANOTHER vector<int>
    }
    else 
    {
      int tail = xs->back();
      int diff = sum - current_sum;
      int m = std::min(tail, sum - tail);
      int next_tail = current_sum + m > sum ? diff : m;
      xs->push_back(next_tail);
    }
  }
}

void print_ints(ints v) // PRINT UTILITY
{
  cout << "[ ";
  for (const int& n : v) { cout << n << "; "; }
  cout << "]" << endl;
}

void print_ints_vec(vector<ints> v) // PRINT UTILITY
{
  cout << "[ \n";
  for (const vector<int>& xs : v) { cout << "  "; print_ints(xs); }
  cout << "]" << endl;
}

Согласитесь, что не очень хочется тратить время и силы на прочтение этого текста лабораторной работы, выискивание ошибки. И не надо! Давайте перепоручим эту задачу анализатору PVS-Studio.


Вот что он сообщает: V506 Pointer to local variable 'next_xs' is stored outside the scope of this variable. Such a pointer will become invalid.


Строка:


xs = &next_xs; // POINTER REASSIGNED TO ANOTHER vector<int>

И действительно, ошибка в том, что сохраняется ссылка на объект, который будет разрушен. На эту ошибку указали другие люди и объяснили, в чём состоит проблема. Однако можно было бы обойтись вообще без ожидания ответа от более опытных коллег. Ведь объяснение ошибки вполне можно получить и из документации анализатора PVS-Studio по диагностике V506.


Вывод


Имейте в виду сценарий использования PVS-Studio для задач обучения. Информация, выдаваемая анализатором, может помочь в обучении, подсказывая человеку, что не так с его кодом. Конечно, это не заменяет обзоров кода другими людьми. Ведь человек не только найдёт ошибку, но даст рекомендации, как лучше написать код. Тем не менее статический анализ всё равно хороший быстрый помощник при обучении программированию.


Дополнительные ссылки:


  1. Статический анализ кода.
  2. PVS-Studio: online версия.
  3. PVS-Studio: бесплатное использование для студентов.

Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. PVS-Studio to help with schoolwork-like tasks in C and C++.

Источник: https://habr.com/ru/company/pvs-studio/blog/675380/


Интересные статьи

Интересные статьи

Мы подготовили для вас 20 рекомендаций по защите от Ransomware-атак, но, чтобы они оказались в полной мере эффективными, для начала поговорим о том, что такое программы-вымогатели и как они работают —...
Введение Примерно тридцать лет назад (когда мне было около двадцати) я, как и многие другие разработчики, мечтал создавать игры. Однако оставался один нерешённый вопрос: для какой платформы их писа...
к/ф «Одержимость» Возможно выглядит как будто нельзя ничего сделать, чтобы научиться работать более усердно, но это не так. На первый взгляд не требуется учиться тому, как работать...
Привет, Хабр! Представляю вашему вниманию перевод статьи «Interview with Weld’s main contributor: accelerating numpy, scikit and pandas as much as 100x with Rust and LLVM». Проработав нескольк...
Приветствую! Хочу рассказать о весьма интересной для разработчика электроники утилите, которую я уже давно применяю в своей профессиональной деятельности. Утилита Power Stage DesignerTM от компан...