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

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

Жанры

Основы программирования в 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

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

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Князь Целитель 4

Ткачев Андрей Юрьевич
4. Князь Целитель
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Князь Целитель 4

Дитя прибоя

Трофимов Ерофей
Дитя прибоя
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Дитя прибоя

Газлайтер. Том 9

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Неучтенный элемент. Том 2

NikL
2. Антимаг. Вне системы
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 2

Неучтенный элемент. Том 6

NikL
6. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 6

Одержимая (авторский сборник)

Дяченко Марина и Сергей
Фантастика:
фэнтези
научная фантастика
7.80
рейтинг книги
Одержимая (авторский сборник)

Древесный маг Орловского княжества 9

Павлов Игорь Васильевич
9. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 9

Собрание сочинений. Т. 20. Плодовитость

Золя Эмиль
Проза:
классическая проза
5.00
рейтинг книги
Собрание сочинений. Т. 20. Плодовитость

Элизиум. Аликс и монеты

Андерсон Александр
1. Элизиум
Фантастика:
фэнтези
сказочная фантастика
8.98
рейтинг книги
Элизиум. Аликс и монеты

Вернувшийся: Корпорация. Том III

Vector
3. Вернувшийся
Фантастика:
космическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Корпорация. Том III

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

NikL
6. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VI

Эволюционер из трущоб. Том 3

Панарин Антон
3. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
6.00
рейтинг книги
Эволюционер из трущоб. Том 3

Точка Бифуркации V

Смит Дейлор
5. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации V