Анализатор обнаружил фрагмент кода, который может привести к использованию невалидного итератора.
Рассмотрим несколько примеров, для которых анализатор выдает данное диагностическое сообщение:
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. |