V522. Dereferencing of the null pointer might take place.


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

Рассмотрим несколько примеров, для которых анализатор выдает диагностическое сообщение V522:

if (pointer != 0 || pointer->m_a) { ... }
if (pointer == 0 && pointer->x()) { ... }
if (array == 0 && array[3]) { ... }
if (!pointer && pointer->x()) { ... }

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

Корректные варианты:

if (pointer == 0 || pointer->m_a) { ... }
if (pointer != 0 && pointer->x()) { ... }
if (array != 0 && array[3]) { ... }
if (pointer && pointer->x()) { ... }

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

Пример кода, где проверка и использование указателя находятся в разных строках

if (ptag == NULL) {
  SysPrintf("SPR1 Tag BUSERR\n");
  psHu32(DMAC_STAT)|= 1<<15;
  spr1->chcr = ( spr1->chcr & 0xFFFF ) |
               ( (*ptag) & 0xFFFF0000 );   
  return;
}

Анализатор предупредит, об опасности в строке "( (*ptag) & 0xFFFF0000 )". Здесь или некорректно написано условие, или вместо 'ptag' должна использоваться другая переменная.

Иногда в тестовых целях программисты сознательно используют разыменование нулевого указателя. Например, анализатор будет генерировать предупреждение там, где используется вот такой макрос:

/// This generate a coredump when we need a
/// method to be compiled but not usabled.
#define elxFIXME { char * p=0; *p=0; }

Лишние предупреждения можно отключить, используя комментарий "//-V522" в тех строках, где используется макрос 'elxFIXME'. Альтернативный вариант, это написать рядом с макросом комментарий специального вида:

//-V:elxFIXME:522

Комментарий может быть написан как до, так и после макроса. Это не имеет значения. Подробнее с методами подавления ложных предупреждений можно познакомиться здесь.

Дополнительная настройка

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

Примером может служить функция malloc. Эта функция может вернуть NULL. Соответственно, если использовать указатель, который вернула функция malloc, без предварительной проверки, то это может привести к разыменованию нулевого указателя.

Иногда у наших пользователей возникает желание изменить поведение анализатора и заставить его считать, что, например, функция malloc не может вернуть NULL. Пользователь может использовать системные библиотеки, в которых ситуации нехватки памяти обрабатываются особым образом.

Также может возникнуть желание подсказать анализатору, что определённая функция может вернуть нулевой указатель.

В этом случае вы можете воспользоваться дополнительными настройками, которые описаны в разделе "Как указать анализатору, что функция может или не может возвращать nullptr".

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

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


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

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

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

goto PVS-Studio;