Время на прочтение
2 мин
Количество просмотров 8.6K
Авторы анализатора PVS-Studio предлагают вам проверить свою внимательность и развлечься. Попробуйте быстро отыскать баг в фрагменте исходного кода и ткнуть в него мышкой.
Анализаторы кода работают без устали и умеют находить множество ошибок, которые сложно заметить. Мы отобрали несколько фрагментов кода, в которых выявили ошибки с помощью PVS-Studio. Все фрагменты взяты из известных Open Source проектов.
Предлагаем вам посоревноваться с анализатором в прозорливости и попробовать самостоятельно найти ошибки. Вам будет предложено 10 случайно выбранных заданий. За верный ответ начисляется одно очко, если баг найден в течение 1 минуты.
Ограничение в 1 минуту сделано для интереса. Иначе вы, скорее всего, верно найдёте и укажете каждую ошибку, так как фрагменты кода короткие. В любом случае относитесь к этому просто как к игре, а не как к настоящему тестированию программистских навыков у вас или ваших коллег
Когда нашли ошибку, выделите её кликом мышки и нажмите кнопку «Ответ». Бывает, что в коде есть сразу несколько мест, куда вы можете «ткнуть» — и ответ зачтётся как правильный. Поясним это на примере.
case FuriHalSubGhzPreset2FSKDev476Async:
preset_name = "FuriHalSubGhzPreset2FSKDev476Async";
break;
FURI_LOG_E(SUBGHZ_PARSER_TAG, "Unknown preset");
default:
Этот код взят из проекта FlipperZero. Анализатор PVS-Studio сообщает, что часть кода никогда не выполняется: V779 [CWE-561, CERT-MSC12-C] Unreachable code detected. It is possible that an error is present. subghz_i.c 44
Кто-то поспешил и использовал макрос логирования после оператора break. Или это следствие неудачного рефакторинга. В любом случае ошибка очевидна, но вот куда именно ткнуть мышкой – вопрос сложнее.
С одной стороны, в качестве ответа можно выбрать оператор break. Он расположен до макроса FURI_LOG_E и прерывает выполнение оператора switch. Значит, проблема здесь.
С другой стороны, можно выбрать макрос логирования. Ведь это недостижимый код.
Так как же быть? Очень просто. В данном случае правильным ответом будет считаться как выделенный оператор break, так и макрос FURI_LOG_E.
Думаем, правила понятны. Желаем вам удачи: начать игру.
Не забудьте, показать этот Quiz вашим коллегам! Развлекайтесь, и безбажного вам кода!
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Andrey Karpov. PVS-Studio’s challenge: can you spot an error?.
Дан код:
unsigned int i;
for (i = 100; i >= 0; --i)
printf("%dn", i);
В коде есть две ошибки.
Первая заключается в том, что используется тип unsigned int
, который работает только со значениями, большими или равными нулю. Поэтому условие цикла for
всегда будет истинно, и цикл будет выполняться бесконечно.
Корректный код, выводящий значения всех чисел от 100 до 1, должен использовать условие i > 0
. Если нам на самом деле нужно вывести нулевое значение, то следует добавить дополнительный оператор printf
после цикла for
.
unsigned int i;
for (i = 100; i > 0; --i)
printf("%dn", i);
printf("%dn", i);
Вторая ошибка — вместо %d
следует использовать %u
, поскольку мы выводим целые значения без знака.
unsigned int i;
for (i = 100; i > 0; --i)
printf("%un", i);
Теперь этот код правильно выведет список чисел от 100 до 1, в убывающем порядке.
Разбор взят из книги Гейл Л. Макдауэлл «Cracking the Coding Interview» (есть в переводе).
Найдите ошибку в коде
12 241
17 ноября 2016 в 16:45
Простая задача, но все же требует внимательности, а также знаний в программировании. Итак, я дам вам небольшой кусочек кода, а вы скажите в чем здесь ошибка.
Вот сам код:
unsigned int i;
for (i = 100; i >= 0; --i)
printf("%dn", i);
В этом коде есть две небольшие ошибки, которые вам стоит найти.
Ошибки
Первым делом, стоит обратить внимания на неправильное определения переменной i
. Дело в том, что в данном случае оно является неверным. Тип unsigned int
говорит о том, что значения этой переменной могут быть только цифры, при чем только положительные цифры без знака минус. Данная запись приводит к тому, что цикл будет выполняться вечно, так как условие всегда будет истинным (true).
Корректный код состоял бы из такого условия i > 0
. Он мог бы вывести все значения, кроме нуля. Цикл завершился бы и тогда мы могли бы после самого цикла прописать еще и вывод 0
. К примеру, у нас бы получилось нечто вроде этого:
unsigned int i;
for (i = 100; i > 0; --i)
printf("%dn", i);
printf("%dn", i);
Вторая ошибка намного проще и заключается в том, что мы используем %d
вместо того чтобы использовать %u
. Поскольку мы выводим числа без минуса, то именно так должно все быть. В итоге у нас получился вот такой код, который верно выводит значения от 100 до 1:
unsigned int i;
for (i = 100; i > 0; --i)
printf("%un", i);
Больше интересных новостей
Добрый день Программа должна высчитывать определитель квадратной матрицы, размер которой вводится с клавиатуры, но при n > 2 программа высчитывает ее неправильно.
К примеру, для матрицы:
41 67 34
0 69 24
78 58 62
Определитель должен равняться 60762, но программа выводит 79212.
Код программы:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
printf("Vvedite razmer n kvadratnoi matrici: ");
scanf("%d", &n);
int i = 0, j = 0, k = 0;
int a[n][n], d = 1, r = 0;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
a[i][j] = rand() % 100;
printf("%d ", a[i][j]);
}
printf("n");
}
if (n == 1)
{
d = a[0][0];
printf("Opredelitel matrici raven - %d", d);
return 0;
}
if (n == 2)
{
d = a[0][0] * a[1][1] - (a[1][0] * a[0][1]);
printf("Opredelitel matrici raven - %d", d);
return 0;
}
if (n > 2)
{
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (j > i)
{
r = a[j][i] / a[i][i];
for (k = 0; k < n; k++) a[j][k] -= r * a[i][k];
}
}
}
}
for(i = 0; i < n; i++) d *= a[i][i];
printf("Opredelitel matrici raven - %d", d);
return 0;
}
Помогите, пожалуйста, найти ошибку.
usva 0 / 0 / 0 Регистрация: 27.03.2023 Сообщений: 5 |
||||
1 |
||||
Найти ошибку в приложенном коде27.03.2023, 17:57. Показов 514. Ответов 10 Метки нет (Все метки)
Для каждого числа из последовательности определить, можно ли поставить внутри числа символ «/» так, чтобы получилась корректная запись даты в формате день/месяц. (без использования массивов, строк).
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
27.03.2023, 17:57 |
10 |
2106 / 1980 / 447 Регистрация: 17.02.2019 Сообщений: 3,178 |
|
27.03.2023, 18:12 |
2 |
usva, а что за ошибка?
0 |
0 / 0 / 0 Регистрация: 27.03.2023 Сообщений: 5 |
|
27.03.2023, 18:15 [ТС] |
3 |
В строке 39 (n = Convert.ToInt32(Console.ReadLine()); пишет
0 |
2106 / 1980 / 447 Регистрация: 17.02.2019 Сообщений: 3,178 |
|
27.03.2023, 18:19 |
4 |
Исключение не обработано наверно вводите не целое число, а что то другое Добавлено через 34 секунды
0 |
0 / 0 / 0 Регистрация: 27.03.2023 Сообщений: 5 |
|
27.03.2023, 18:23 [ТС] |
5 |
Ввожу целые числа. Подскажите, пожалуйста, а как реализовать вызов метода? Я на С# вообще не программировал, просто дали задание, поэтому не все получается реализовывать.
0 |
293 / 202 / 49 Регистрация: 12.04.2020 Сообщений: 1,035 |
|
27.03.2023, 18:56 |
6 |
Я на С# вообще не программировал, просто дали задание а как дали задание если вас не научили на шарпе писать?
0 |
January29 2106 / 1980 / 447 Регистрация: 17.02.2019 Сообщений: 3,178 |
||||||||
27.03.2023, 19:04 |
7 |
|||||||
Сообщение было отмечено usva как решение Решение
а как реализовать вызов метода? метод вставлять в Main()
и вот еще, вы объявили переменную bool isOK; запомните где маленькие и большие буковки. Добавлено через 3 минуты код
0 |
2629 / 1597 / 852 Регистрация: 23.02.2019 Сообщений: 3,876 |
|
27.03.2023, 19:09 |
8 |
без использования массивов А у вас массив есть.
0 |
0 / 0 / 0 Регистрация: 27.03.2023 Сообщений: 5 |
|
27.03.2023, 20:14 [ТС] |
9 |
Исправил все недочеты, как в вашем коде, все равно выдает ту же ошибку Добавлено через 56 секунд Добавлено через 1 минуту
0 |
January29 2106 / 1980 / 447 Регистрация: 17.02.2019 Сообщений: 3,178 |
||||
27.03.2023, 21:11 |
10 |
|||
все равно выдает ту же ошибку ну не знаю все у меня вводится без ошибок, вы наверно не то вводите или нажимаете Enter без ввода чисел. Лучше я думаю запрос делать что вводить, ну и можно конечно проверку провернуть. Код
я вот только не пойму, зачем переменную day вводить в цикле for. Так просто спросил.
0 |
0 / 0 / 0 Регистрация: 27.03.2023 Сообщений: 5 |
|
28.03.2023, 07:00 [ТС] |
11 |
Большое спасибо, разобрался, все работает
0 |