>
>
>
V783. Possible dereference of invalid i…


V783. Possible dereference of invalid iterator 'X'.

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

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

if (iter != vec.end() || *iter == 42) { ... }
if (iter == vec.end() && *iter == 42) { ... }

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

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

if (iter != vec.end() && *iter == 42) { ... }
if (iter == vec.end() || *iter == 42) { ... }

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

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

if (iter == vec.end()) {
  std::cout << "Error: " << *iter << std::endl;
  throw std::runtime_error("foo");
}

Анализатор предупредит об опасности в выражении '*iter'. Здесь или некорректно написано условие, или вместо 'iter' должна использоваться другая переменная.

Анализатор также находит ошибки, когда использование итератора находится до его проверки.

Пример:

std::cout << "Element is " << *iter << std::endl;
if (iter == vec.end()) {
  throw std::runtime_error("");
}

Здесь проверка не имеет смысла, так как если итератор невалидный, то выше по коду произойдёт его разыменование. Скорее всего нужно добавить дополнительную проверку итератора:

if (iter != vec.end()) {
  std::cout << "Element is " << *iter << std::endl;
}
if (iter == vec.end()) {
  throw std::runtime_error("");
}

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

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