Linux программирование в примерах | страница 71
• Необходимо предпринять чрезвычайные меры осторожности в следующих случаях
• освобождать лишь память, выделенную с помощью соответствующих процедур,
• освобождать память один и только один раз,
• освобождать неиспользуемую память и
• не допускать «утечки» динамически выделяемой памяти.
• POSIX предоставляет для удобства функцию >strdup()
, a GLIBC предоставляет функции >getline()
и >getdelim()
для чтения строк произвольной длины. Функции интерфейса низкоуровневых системных вызовов >brk()
и >sbrk()
предоставляют непосредственный, но примитивный доступ к выделению и освобождению памяти. Если вы не создаете свой собственный распределитель памяти, следует избегать их. Существует функция >alloca()
для выделения памяти в стеке, но ее использование не рекомендуется. Подобно умению распознавать ядовитый плющ, про нее нужно знать лишь для того, чтобы избегать ее.
Упражнения
1. Начав со структуры —
>struct line {
> size_t buflen;
> char *buf;
> FILE* fp;
>};
— напишите свою собственную функцию >readline()
, которая будет читать строки любой длины. Не беспокойтесь о строках, продолженных с помощью обратного слеша. Вместо использования >fgetc()
для чтения строк используйте >getc()
для чтения одного символа за раз.
2. Сохраняет ли ваша функция завершающий символ конца строки? Объясните, почему.
3. Как ваша функция обрабатывает строки, оканчивающиеся CR-LF?
4. Как вы инициализируете структуру? В отдельной процедуре? С помощью документированных условий для определенных значений в структуре?
5. Как вы обозначаете конец файла? Как вы указываете, что возникла ошибка ввода/вывода? Должна ли ваша функция сообщать об ошибках? Объясните, почему.
6. Напишите программу, которая использует вашу функцию для ее тестирования, а также другую программу, создающую входные данные для первой программы. Протестируйте функцию.
7. Перепишите вашу функцию с использованием >fgets()
и протестируйте ее. Является ли новый код более сложным или менее сложным? Какова его производительность по сравнению с версией >getc()
?
8. Изучите страницу справки V7 для end(3) (>/usr/man/man3/end.3
в дистрибутиве V7). Пролила ли она свет на то, как может работать '>sbrk(0)
'?
9. Усовершенствуйте >ch03-memaddr.c
так, чтобы она печатала расположение аргументов и переменных окружения. В какой области адресного пространства они находятся?
Глава 4
Файлы и файловый ввод/вывод
Данная глава описывает базовые файловые операции: открытие и создание файлов, чтение и запись в них, перемещение в них и их закрытие. По ходу дела она представляет стандартные механизмы для обнаружения ошибок и сообщений о них. Глава заканчивается описанием того, как установить длину файла и принудительно сбросить данные файла и вспомогательные данные на диск.