Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

Вы также должны убедиться в том, что у выражения макроса

assert
нет побочных эффектов. Например, если вы применяете вызов функции с побочным эффектом, этот побочный эффект не проявится в рабочем коде с отключенными макросами
assert
.

Выполните упражнение 10.2.

Упражнение 10.2. Программа assert.c.

Далее приведена программа assert.c, определяющая функцию, которая должна принимать положительное значение. Она защищает от ввода некорректного аргумента благодаря применению макроса

assert
.

После включения заголовочного файла assert.h и функции "квадратный корень", проверяющей положительное значение параметра, вы можете писать функцию

main
.

#include <stdio.h>

#include <math.h>

#include <assert.h>

#include <stdlib.h>

double my_sqrt(double x) {

 assert(x >= 0.0);

 return sqrt(x);

}

int main {

 printf("sqrt +2 = %g\n", my_sqrt(2.0));

 printf("sqrt -2 = %g\n", my_sqrt(-2.0));

 exit(0);

}

Теперь при выполнении программы вы увидите нарушение в макросе

assert
при передаче некорректного значения. Точный формат сообщения о нарушении условия макроса assert в разных системах разный.

$ сс -о assert assert.с -lm

$ ./assert

sqrt +2 = 1.41421

assert: assert.c:7: my_sqrt: Assertion 'x >= 0.0' failed.

Aborted

$

Как это работает

Когда вы попытаетесь вызвать функцию

my_sqrt
с отрицательным числом, макрос
assert
даст сбой. Он предоставляет файл и номер строки, в которой нарушено условие и само нарушенное условие. Программа завершается прерыванием
abort
. Это результат вызова
abort
макросом
assert
.

Если вы перекомпилируете программу с опцией

– DNDEBUG
, макрос
assert
не компилируется, и вы получаете
NaN
(Not a Number, не число) — значение, указывающее на неверный результат при вызове функции
sqrt
из функции
my_sqrt
.

$ cc -о assert -DNDEBUG assert.с -lm

$ ./assert

sqrt +2 = 1.41421

sqrt -2 = nan

$

Некоторые более старые версии математической библиотеки генерируют исключение для математической ошибки, и ваша программа будет остановлена с сообщением "Floating point exception" ("Исключение для числа с плавающей точкой") вместо возврата NaN.

Устранение ошибок использования памяти

Распределение динамической памяти — богатый источник ошибок, которые трудно выявить. Если вы пишете программу, применяющую функции

malloc
и
free
для распределения памяти, важно внимательно следить за блоками, которые вы выделяете, и быть уверенным в том, что не используется блок, который вы уже освободили.

Обычно блоки памяти выделяются функцией

malloc
и присваиваются переменным-указателям. Если переменная-указатель изменяется, и нет других указателей, указывающих на блок памяти, он становится недоступным. Это утечка памяти, вызывающая увеличение размера программы. Если вы потеряете большой объем памяти, скорость работы вашей системы, в конце концов, снизится, и система уйдет за пределы памяти.

Если вы записываете в область, расположенную после конца выделенного блока (или перед началом блока), вы с большой долей вероятности повредите структуры данных, используемые библиотекой malloc, следящей за распределением памяти. В этом случае в какой-то момент времени вызов

malloc
или даже
free
приведет к нарушению сегментации, и ваша программа завершится аварийно. Определение точного места возникновения сбоя может оказаться очень трудной задачей, поскольку нарушение могло возникнуть задолго до события, вызвавшего аварийное завершение программы.

Неудивительно, что существуют коммерческие и бесплатные средства, способные помочь в решении проблем этих двух типов. Например, есть много разных версий функций

malloc
и
free
, которые содержат дополнительный код для проверки выделения и освобождения блоков памяти и пытаются учесть двойное освобождение блока и другие типы неправильного использования памяти.

ElectricFence

Библиотека ElectricFence была разработана Брюсом Перенсом (Bruce Perens). Она доступна как необязательный компонент в некоторых дистрибутивах Linux, таких как Red Hat (Enterprise и Fedora), SUSE и openSUSE, и может быть легко найдена в Интернете. Это средство пытается применять виртуальную память системы Linux для защиты памяти, используемой функциями

malloc
и
free
, и аварийного останова программы в момент повреждения памяти.

Выполните упражнение 10.3.

Упражнение 10.3. Применение библиотеки ElectricFence

Далее приведена программа efence.c, которая выделяет память с помощью функции

malloc
и пишет данные за концом выделенного блока. Познакомьтесь с ней и посмотрите, что произойдет.

#include <stdio.h>

#include <stdlib.h>

int main {

 char *ptr = (char *)malloc(1024);

 ptr[0] = 0;

 /* Теперь пишет за пределы блока */

 ptr[1024] = 0;

 exit(0);

}

Когда вы откомпилируете и выполните программу, то не увидите некорректного поведения. Однако вероятно, что область памяти, выделенная

malloc
, повреждена, и вы, в конце концов, попадете в беду.

$ cc -о efence efence.с

$ ./efence

Поделиться:
Популярные книги

Зеркало силы

Кас Маркус
3. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Зеркало силы

Имя нам Легион. Том 1

Дорничев Дмитрий
1. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 1

Второгодка. Книга 3. Ученье свет

Ромов Дмитрий
3. Второгодка
Фантастика:
городское фэнтези
сказочная фантастика
альтернативная история
5.00
рейтинг книги
Второгодка. Книга 3. Ученье свет

Первый среди равных

Бор Жорж
1. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных

Революция

Валериев Игорь
9. Ермак
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Революция

Симфония теней

Злобин Михаил
3. Хроники геноцида
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Симфония теней

Дважды одаренный. Том VI

Тарс Элиан
6. Дважды одаренный
Фантастика:
аниме
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
Дважды одаренный. Том VI

Сирота

Шмаков Алексей Семенович
1. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Сирота

Звездная Кровь. Изгой II

Елисеев Алексей Станиславович
2. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
технофэнтези
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой II

Имперец. Том 5

Романов Михаил Яковлевич
4. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
6.00
рейтинг книги
Имперец. Том 5

Кодекс Охотника. Книга XXVI

Винокуров Юрий
26. Кодекс Охотника
Фантастика:
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXVI

Тринадцатый IV

NikL
4. Видящий смерть
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Тринадцатый IV

На границе империй. Том 9. Часть 2

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Кодекс Крови. Книга ХVI

Борзых М.
16. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVI