![]() Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву ![]() Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Значение вне допустимой области
(баг частый, мелкий) Пример 1. int x, y, z; // какой-то код if ((int p = x + y) < z) return 1; Else return 0; Если значение суммы x + y выходит за пределы диапазона значений типа int, возникает переполнение, и бит знака устанавливается в 1. Условие оказывается истинным, и вместо нуля возвращается единица. Пример 2. unsigned char a = 100; //01100100 двоичное unsigned char b = 200; //11001000 unsigned char c = a + b; // 100101100 -> 00101100: переполнение В итоге c = 100 + 200 будет равно 44. Пример 3. int a = 1000; char b = a; /* переполнение при преобразовании int к char. В итоге b будет содержать лишь 8 младших битов a */ printf (“ b = %i\n”, b); // будет выведено b = -24 Еще один вид ошибок связан с интерпретацией данных. Известно, что тип результата арифметических операций совпадает с наивысшим из типов операндов. Типы ранжируются так: double > float > int > char. Прилагательные long, long long, unsigned повышают ранг типа. Так что unsigned int > int. Если из небольшого значения а типа unsigned int вычесть какое – нибудь число, большее а, то отрицательный результат будет интерпретирован как очень большое положительное число. Такого рода ошибки часто возникают при работе с функциями, возвращающими тип size_t, например, length(). Пример. /*Поиск вхождения строки “qwert” в строку s. Функция возвращает позицию самого левого вхождения или -1 */ int find (char *s) { for (int i =0; i < strlen(s) – 5; ++i) if (s[ i ] ==’q’ && s[i + 1] == ‘w’ && s[i + 2] == ‘e’ && s[i + 3] == ‘r’ && s[i + 4] == ‘t’) return i; return -1; } Если длина строки s окажется меньше 5, то значение strlen(s) – 5 будет интерпретировано как огромное положительное число, что приведет к выходу за пределы строки и непредсказуемым последствиям. Возможные верные варианты цикла: for (int i =0; i < (int) strlen(s) – 5; ++i) или for (int i =0; i < (int)(strlen(s) – 5); ++i) Можно предусмотреть случаи, когда s имеет длину < 5: if (strlen(s) < 5) return -1;
Переполнение буфера (баг частый, катастрофический) Переполнение буфера – ситуация, в которой данные записываются за допустимыми пределами выделенной области памяти (буфера). Вообще говоря, когда массив объявляется, его размер задается явно, и любой доступ к этому массиву должен быть ограничен диапазоном корректных индексов. Любой код, который записывает данные в буфер без проверки размера, может вызвать переполнение буфера.
int main () { char ch [ 10 ]; gets (ch); // может вызвать переполнение буфера ... } Баг может повлечь за собой непреднамеренные нарушения в работе системы, а также следующие уязвимости: - «нападение на стек» - изменение адреса возврата с целью выполнения вредоносного кода - перезапись указателя с целью получить определенные данные - переполнение кучи. 3. 4. Арифметические исключения (баги частые, крупные / мелкие) Арифметические исключения – класс ошибок. Некоторые примеры: · Деление на 0 · Извлечение квадратного корня из отрицательного числа · Исключения при работе с вещественными числами в формате с плавающей точкой Последствия ошибки могут варьироваться от получения неожиданных результатов до аварийного завершения программы. Пример. Вычисление площади треугольника по трем его сторонам (формула Герона). #include < stdio.h > #include < conio.h > #include < math.h > float area (float a, float b, float c) { float P = a + b + c; float p = P/2; float s = sqrt (p * (p – a) * (p – b) * (p – c)); return s; } int main() { float test[4][3] = { { 3, 4, 5 }, { 5, 12, 13 }, { -3, -4, -5 }, { 3, 4, 8 } }; for (int i = 0; i < 4; ++i) printf (“ area (%f, %f, %f) = %f\n”, test [ i ] [ 0 ], test [ i ] [ 1 ], test [ i ] [ 2 ], area (test [ i ] [ 0 ], test [ i ] [ 1 ], test [ i ] [ 2 ])) getch (); } Вывод программы: area (3.000000, 4.000000, 5.000000) = 6.000000 area (5.000000, 12.000000, 13.000000) = 30.000000 area (-3.000000, -4.000000,-5.000000) = 6.000000 area (3.000000, 4.000000, 8.000000) = -1.#IND00 При попытке вычислить площадь треугольника со сторонами 3, 4, 8 возникла ошибка, связанная с попыткой извлечь квадратный корень из отрицательного числа. Но хуже то, что площадь треугольника с тремя отрицательными сторонами оказалась вычисленной и положительной, и никакого исключения не возникло. Решение в данном примере состоит в том, чтобы сделать защиту путем контроля вводимых данных: a > 0, b > 0, c > 0, a + b > c, a + c > b, b + c > a. Off - by – one (баг частый, крупный) Это одна из наиболее общих ошибок. Примеры: · Начальное значение переменной цикла for равно 1 вместо 0 или наоборот · Написание <= N вместо < N или наоборот · Цикл по элементам массива 1.. n вместо 0.. n-1 и т.д. Приоритет операторов (баг частый, мелкий) Ошибку особенно трудно заметить напрямую. Чтобы избежать возникновения ошибки, достаточно знать правила приоритета операций языка программирования. Не следует писать длинных и сложных предложений. Имеет смысл использовать скобки для явного задания приоритетов, даже если они излишни (это к тому же облегчает чтение кода).
Пример: if ((x==0) && (y == 1)) z=1; else z=2;
|
||||||
Последнее изменение этой страницы: 2021-03-09; просмотров: 73; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.138.34.31 (0.012 с.) |