Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Teoria 158783 .doc
Скачиваний:
6
Добавлен:
25.09.2019
Размер:
1.72 Mб
Скачать

Процедуры Getmem и Freemem

Использование процедур Getmem и Freemem – это второй метод работы с динамическими переменными.

Вызов процедуры Getmem имеет следующий формат:

Getmem (P, Size);

Здесь P - указатель любого типа, Size – выражение типа Word.

Процедура Getmem выделяет из Heap-области (хип-область, область кучи, область динамической памяти) блок памяти заданного размера Size (порождает динамическую переменную размера Size) и адрес этого блока присваивает ссылочной переменной P. Максимальный размер блока – 65521байт (64К байта – $F (смещение)).

Для освобождения блока памяти, занимаемого динамической переменной, используется процедура Freemem:

Freemem (P, Size)

Здесь P – указатель произвольного типа, которому предварительно было присвоено значение процедурой Getmem или оператором присваивания; значение Size должно точно соответствовать размеру переменной, размещенной до этого процедурой Getmem.

Процедура Freemem уничтожает динамическую переменную P^, занимаемая ею память считается свободной, значение P становится неопределенным.

Таким образом, действие процедур Getmem/Freemem аналогично действию процедур New/Dispose – порождается и уничтожается динамическая переменная.

Пример 6.8.

Эквивалентные фрагменты программ, использующие процедуры Getmem/Freemem и New/Dispose.

Type

T = <Тип>;

Var

P: ^T;

B egin

New (P); Getmem (P, Sizeof(T));

Эквивалентны

Dispose (P); Freemem (P, Sizeof(T));

В общем случае процедуры Getmem/Freemem дают большую свободу действий по сравнению с процедурами New/Dispose, так как позволяют работать без привязки к конкретному типу переменных.

Пример 6.9.

Использование процедур Getmem/Freemem. Различная интерпретация выделенной области памяти.

Type

Zap = Record

X, Y: Integer;

End;

St = String [20];

Var

P: Pointer;

Begin

Getmem (P, 100); {Выделение блока памяти размером 100 байт, адрес

этого блока присвоен ссылочной переменной Р}

Zap(P^).X := 124; {Интерпретация выделенной области как записи –

блоку памяти, связанному с указателем Р,

присваивается тип Zap}

Zap(P^).Y := 47; {Интерпретация выделенной области как записи}

Real(P^) := 0.213; {Интерпретация выделенной области как Real}

St(P^) := ’ПРОГРАММИРОВАНИЕ’; {Интерпретация выделенной области

как строки}

Freemem (P, 100); {Освобождение блока памяти размером 100 байт}

Процедуры Mark и Release

Процедуры Mark (пометить) и Release (освободить) позволяют повысить эффективность работы с динамической памятью.

Обращение к процедуре Mark имеет следующий вид:

Mark (P1);

Здесь P1 – переменная типа указатель, ссылающаяся на переменную какого угодно типа.

Процедура Mark присваивает своему параметру P1 адрес начала свободной области динамической памяти.

Помеченная область с помощью процедур New или Getmem используется для размещения отдельных динамических переменных.

Когда данные динамические переменные окажутся ненужными, занимаемую ими память можно освободить. Для этого используется процедура Release с тем же параметром, что и в предыдущем обращении к процедуре Mark:

Release (P1);

Процедура Release освобождает память, начиная с адреса, полученного в результате выполнения последней процедуры Mark. Значение указателя P1 после выполнения процедуры Release равно Nil.

Схематически представление работы с динамической памятью без и с использованием процедур Mark/Release иллюстрирует Рисунок 6 .55.

Рисунок 6.55 - Схематическое представление работы с динамической памятью без и с использованием процедур Mark/Release

Параметр процедуры Mark нельзя использовать в качестве параметра процедур New, Getmem и его нельзя изменять (по крайней мере до его использования в соответствующей процедуре Release).

Возможна вложенность процедур Mark. Тогда каждой процедуре Mark соответствует своя процедура Release.

Пример 6.10.

Использование вложенных процедур Mark/Release.

Var

P1, P2: Pointer;

P, Q, X: ^Integer;

B egin

Mark (P1);

New (P);

Внешние процедуры Mark/Release

New (Q);

Mark (P2);

New (X);

Release (P2);

Release (P1);

В одной и той же программе не рекомендуется использовать одновременно процедуры Dispose или Freemem и Mark/Release, так как это может привести к непредсказуемым результатам (механизмы управления свободной памятью для процедур Dispose, Freemem и Mark/Release существенно различаются).

В общем случае вместо любой автоматической переменной в программе можно использовать динамическую переменную.

Основное достоинство использования динамических переменных – экономия памяти компьютера.

Недостатки использования динамических переменных по сравнению с автоматическими:

  • удлиняется текст программы за счет использования процедур New/Dispose, Mark/Release, Getmem/Freemem;

  • снижается наглядность программы за счет использования переменной с указателем (динамической переменной);

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]