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. |