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

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

Жанры

Linux программирование в примерах
Шрифт:

3.2.1.6. Подведение итогов из GNU Coding Standards

Чтобы подвести итоги, процитируем, что говорит об использовании процедур выделения памяти GNU Coding Standards:

Проверяйте каждый вызов

malloc
или
realloc
на предмет возвращенного нуля. Проверяйте
realloc
даже в том случае, если вы уменьшаете размер блока; в системе, которая округляет размеры блока до степени двойки,
realloc
может получить другой блок, если вы запрашиваете меньше памяти.

В Unix

realloc
может разрушить блок памяти, если она возвращает ноль. GNU
realloc
не содержит подобной ошибки: если она завершается неудачей, исходный блок остается без изменений. Считайте, что ошибка устранена. Если вы хотите запустить свою программу на Unix и хотите избежать потерь в этом случае, вы можете использовать GNU
malloc
.

Вы должны считать, что

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

В этих трех коротких абзацах Ричард Столмен (Richard Stallman) выразил суть важных принципов управления динамической памятью с помощью

malloc
. Именно использование динамической памяти и принцип «никаких произвольных ограничений» делают программы GNU такими устойчивыми и более работоспособными по сравнению с их Unix-двойниками.

Мы хотим подчеркнуть, что стандарт С требует, чтобы

realloc
не разрушал оригинальный блок памяти, если она возвращает
NULL
.

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

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

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

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Я до сих пор князь. Книга XXII

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

Анти-Ксенонская Инициатива

Вайс Александр
7. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Анти-Ксенонская Инициатива

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

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

Лекарь Империи 3

Карелин Сергей Витальевич
3. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.00
рейтинг книги
Лекарь Империи 3

Зеркало силы

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

Законы Рода. Том 6

Андрей Мельник
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Петля, Кадетский корпус. Книга девятая

Алексеев Евгений Артемович
9. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский корпус. Книга девятая

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство

Сирота

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

Любовь Носорога

Зайцева Мария
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Любовь Носорога

Черный Маг Императора 19

Герда Александр
19. Черный маг императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 19

Иной. Том 1. Школа на краю пустыни

Amazerak
1. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.75
рейтинг книги
Иной. Том 1. Школа на краю пустыни

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19