Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

Вызовы brk и sbrk

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

Упражнение 12.1. Односвязный список нашего примера может использоваться для реализации стека, в котором первым используется последний добавленный элемент. Процедура add_member будет соответствовать операции вставки (push) данных в стек. Напишите процедуру, реализующую обратную операцию извлечения (pop) данных из стека за счет удаления первого элемента списка.

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

12.3. Ввод/вывод с отображением в память и работа с памятью

При выполнении процессом ввода/вывода больших объемов данных с диска, возникают накладные расходы, связанные с двойным копированием данных сначала с диска во внутренние буферы ядра, а потом из этих буферов в структуры данных процесса. Ввод/вывод с отображением в память увеличивает скорость доступа к файлу, напрямую «отображая» дисковый файл в пространство памяти процесса. Как уже было видно на примере работы с разделяемой памятью в разделе 8.3.4, работа с данными в адресном пространстве процесса является наиболее эффективной формой доступа. (Но хотя использование ввода/вывода с отображением в память и приводит к ускорению доступа к файлам, его интенсивное использование может уменьшить объем памяти, доступный другим средствам, использующим память процесса.)

Вскоре будут рассмотрены системные вызовы mmap и munmap. Но вначале опишем несколько простых процедур для работы с блоками памяти.

Описание

uses stdio;

function memset(buf:pointer; character:longint; size:longint):pointer;

function memcpy(buf1:pointer; const buf2:pointer; size:longint):pointer;

function memmove(buf1:pointer; const buf2:pointer; size:longint):pointer;

function memcmp(const buf1, buf2:pointer; size:longint):longint;

function memchr(const buf:pointer; character:longint; size:longint):

pointer;

Для инициализации массивов данных можно использовать процедуру memset, записывающую значения character в первые size байтов массива памяти buf.

Для прямого копирования одного участка памяти в другой можно использовать любую из процедур memcpy или memmove. Обе эти функции перемещают size байт памяти, начиная с адреса buf1 в участок, начинающийся с адреса buf2. Разница между этими двумя функциями состоит в том, что функция memmove гарантирует, что если области источника и адресата копирования buf1 и buf2 перекрываются, то при перемещении данные не будут искажены. Для этого функция memmove вначале копирует сегмент buf2 во временный массив, а затем копирует данные из временного массива в сегмент buf1 (или использует более разумный алгоритм).

Функция memcmp работает аналогично функции strcmp. Если первые size байтов buf1 и buf2 совпадают, то функция memcmp вернет значение 0.

Функция memchr проверяет первые size байтов buf и возвращает либо адрес первого вхождения символа character, либо значение nil. Процедуры memset, memcpy и memmove в случае успеха возвращают значение первого параметра.

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal