Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 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; просмотров: 68; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.58.252.8 (0.008 с.) |