Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top

Вебинар: Использование статических анализаторов кода при разработке безопасного ПО - 19.12

>
>
>
V826. Consider replacing standard conta…
menu mobile close menu
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Микрооптимизации (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C++)
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
toggle menu Оглавление

V826. Consider replacing standard container with a different one.

21 Июл 2020

Анализатор обнаружил контейнер из стандартной библиотеки C++, который можно заменить на другой контейнер в целях оптимизации.

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

В сообщении указывается причина замены:

  • "The size is known at compile time" – размер контейнера известен во время компиляции, возможна замена на статический массив (std::array).
  • "Elements are added, read and erased only from front/back" – контейнер реализует LIFO-очередь, можно использовать 'std::stack'.
  • "Elements are added to front/back, read and erased from the opposite side" – контейнер реализует FIFO-очередь, можно использовать 'std::queue'.
  • "Insertion and removal of elements occur at either side of the container" – элементы добавляются или удаляются с головы и с хвоста. В этом случае эффективно использовать 'std::deque' или 'std::list'.
  • "Insertions occur at the front side, and the container is traversed forward" – элементы добавляются только с головы и происходит обход в направлении хвоста. Контейнер используется, как 'std::forward_list'.
  • "Insertions occur at the back side, and the container is traversed" – элементы добавляются в хвост, происходит обход в любом направлении. Для такого использования подходит 'std::vector'.
  • "Contiguous placement of elements in memory can be more efficient" – если использовать 'std::vector', то алгоритмическая сложность операций не изменится, но последовательное расположение элементов в памяти может улучшить производительность.
  • "Overall efficiency of operations will increase" – контейнер выбран на основании статистического анализа.

Пример:

void f()
{
  std::vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);

  for (auto value : v)
  {
    std::cout << value << ' ';
  }
}

Анализатор выдает следующее сообщение:

V826. Consider replacing the 'v' std::vector with std::array. The size is known at compile time.

Здесь размер вектора известен во время компиляции. Если использовать вместо него 'std::array', можно избежать динамической аллокации памяти. Оптимизированный код:

void f()
{
  std::array a{1, 2, 3};
}

Анализатор не предлагает такую замену, если суммарный размер элементов превышает 16 килобайт, а также если вектор приходит в функцию снаружи, возвращается из функции, или передается в другую функцию параметром.

В следующем фрагменте кода сообщение не выдается несмотря на то, что размер контейнера известен:

std::vector<int> f()
{
  std::vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);

  return v;
}

Следующий пример, который можно оптимизировать:

void f(int n)
{
  std::vector<int> v;

  for (int i = 0; i < n; ++i)
  {
    v.push_back(i);
  }

  for (int i = 0; i < n; ++i)
  {
    std::cout << v.back() << ' ';
    v.pop_back();
  }
}

Анализатор выдает следующее сообщение:

V826. Consider replacing the 'v' std::vector with std::stack. Elements are added, read and erased only from front/back.

Здесь элементы добавляются в хвост вектора, а затем происходит их последовательное чтение и удаление. Вектор используется, как 'std::stack'. Можно произвести замену. Оптимизированный код:

void f(int n)
{
  std::stack<int> v;

  for (int i = 0; i < n; ++i)
  {
    v.push(i);
  }

  for (int i = 0; i < n; ++i)
  {
    std::cout << v.top() << ' ';
    v.pop();
  }
}

Следующий пример, который можно оптимизировать:

void f(int n)
{
  std::deque<int> d;
  for (int i = 0; i < n; i++)
  {
    d.push_back(i);
  }

  for (auto value : d)
  {
    std::cout << value << ' ';
  }
}

Анализатор выдает следующее сообщение:

V826. Consider replacing the 'd' std::deque with std::vector. Contiguous placement of elements in memory can be more efficient.

В этом случае 'std::deque' и 'std::vector' не отличаются с точки зрения алгоритмической сложности. Однако, в случае с вектором элементы в памяти будут расположены последовательно. Это может увеличить производительность, так как последовательный доступ к памяти позволяет эффективно использовать кэш процессора. Оптимизированный код:

void f(int n)
{
  std::vector<int> d;
  for (int i = 0; i < n; i++)
  {
    d.push_back(i);
  }

  for (auto value : d)
  {
    std::cout << value << ' ';
  }
}
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам