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

на главную

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

3.2.1.7. Использование персональных программ распределения

Набор функций с

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

Вы можете написать персональную

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

Например, GNU awk (gawk) использует эту методику. Выдержка из файла

awk.h
в дистрибутиве
gawk
(слегка отредактировано, чтобы уместилось на странице):

#define getnode(n) if (nextfree) n = nextfree, \

 nextfree = nextfree->nextp; else n = more_nodes

#define freenode(n) ((n)->flags = 0, (n)->exec_count = 0,\

 (n)->nextp = nextfree, nextfree = (n))

Переменная

nextfree
указывает на связанный список структур NODE. Макрос
getnode
убирает из списка первую структуру, если она там есть. В противном случае она вызывает
more_nodes
, чтобы выделить новый список свободных структур
NODE
. Макрос
freenode
освобождает структуру
NODE
, помещая его в начало списка.

ЗАМЕЧАНИЕ. Первоначально при написании своего приложения делайте это простым способом: непосредственно используйте

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

3.2.1.8. Пример: чтение строк произвольной длины

Поскольку это, в конце концов, Программирование на Linux в примерах, настало время для примера из реальной жизни. Следующий код является функцией

readline
из GNU Make 3.80 (
ftp://ftp.gnu.org/gnu/make/make-3.80.tar.gz
). Ее можно найти в файле
read.c
.

Следуя принципу «никаких произвольных ограничений», строки в

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

Вторичной задачей является распоряжение продлением строк. Как и в С, строки, заканчивающиеся обратным слешем, логически продолжаются со следующей строки. Используется стратегия поддержания буфера.

В нем хранится столько строк, сколько помещается в буфер, причем указатели отслеживают начало буфера, текущую строку и следующую строку. Вот структура:

struct ebuffer {

 char *buffer; /* Начало текущей строки в буфере. */

 char *bufnext; /* Начало следующей строки в буфере. */

 char *bufstart; /* Начало всего буфера. */

 unsigned int size; /* Размер буфера для malloc. */

 FILE *fp; /* Файл или NULL, если это внутренний буфер. */

 struct floc floc; /* Информация о файле в fp (если он есть). */

};

Поле

size
отслеживает размер всего буфера, a
fp
является указателем типа
FILE
для файла ввода. Структура floc не представляет интереса при изучении процедуры.

Функция возвращает число строк в буфере. (Номера строк здесь даны относительно начала функции, а не исходного файла.)

1 static long

2 readline(ebuf) /* static long readline(struct ebuffer *ebuf) */

3 struct ebuffer *ebuf;

4 {

5 char *p;

6 char *end;

7 char *start;

8 long nlines = 0;

9

10 /* Использование строковых буферов и буферов потоков достаточно

11 различается, чтобы использовать разные функции. */

12

13 if (!ebuf->fp)

14 return readstring(ebuf);

15

16 /* При чтении из файла для каждой новой строки мы всегда

17 начинаем с начала буфера. */

18

19 p = start = ebuf->bufstart;

20 end = p + ebuf->size;

21 *p = '\0';

Для начала заметим, что GNU Make написан на С K&R для максимальной переносимости. В исходной части объявляются переменные, и если ввод осуществляется из строки (как в случае расширения макроса), код вызывает другую функцию,

readstring
(строки 13 и 14). Строка '
!ebuf->fp
' (строка 13) является более короткой (и менее понятной, по нашему мнению) проверкой на пустой указатель; это то же самое, что и '
ebuf->fp==NULL
'.

Строки 19-21 инициализируют указатели и вводят байт NUL, который является символом завершения строки С в конце буфера. Затем функция входит в цикл (строки 23–95), который продолжается до завершения всего ввода.

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

Путь одиночки. Книга 2

Понарошку Евгений
2. Одиночка
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Путь одиночки. Книга 2

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Ветер с севера

Щепетнов Евгений Владимирович
5. Нед
Фантастика:
фэнтези
8.83
рейтинг книги
Ветер с севера

Убивать чтобы жить 8

Бор Жорж
8. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 8

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

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

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

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

Я еще не князь. Книга XIV

Дрейк Сириус
14. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще не князь. Книга XIV

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

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

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

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

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

Гримуар тёмного лорда I

Грехов Тимофей
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар тёмного лорда I

#Бояръ-Аниме. Газлайтер. Том 13

Володин Григорий Григорьевич
13. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
фэнтези
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 13

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

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

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