Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 129

11.5.2. Процедуры Dispose и FreeMem


Процедура Dispose (VAR P : Pointer ) освобождает память, занимаемую динамической переменной P^, на которую указывает ее

- 202 -

аргумент P. Эта процедура работает только с типизированными ссылочными переменными. Во избежание проблем вызовы Dispose должны быть парны вызовам New с тем же аргументом и ни в коем случае не применяться к неразмещенным ссылкам.

После выполнения процедуры Dispose значение ссылки P не определено, как и значение разыменования P^.

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

FreeMem( VAR Р : Pointer; Size : Word ).

Она производит освобождение участка памяти, начиная с адреса, передаваемого ей в первом параметре (ссылке или указателе P) и имеющего размер, определяемый вторым параметром (Size). При использовании процедуры FreeMem нельзя забывать, что размер освобождаемого блока должен точно соответствовать размеру, заданному при его размещении посредством GetMem или New. В противном случае либо возникнут потерянные байты, если размер блока при освобождении оказался меньше (а это мусор в памяти), либо в дальнейшем возможна потеря части данных, непосредственно примыкавших к этой области, если размер освобождаемого блока больше ранее отведенного. Последнее чревато особо неприятными последствиями.

Вызовы FreeMem, как и Dispose, в идеале должны быть парны вызовам GetMem. Хотя на практике можно использовать FreeMem вместо Dispose.

Значение ссылочной переменной P после вызова FreeMem считается неопределенным, и ссылаться на P^ в этом случае не стоит.

Если сразу за операторами Dispose или FreeMem следуют конец всей программы или оператор Halt и ему подобные, то можно, в принципе, исключить из программы эти последние процедуры освобождения. Это не совсем по правилам, но может доставить немного радости тем, кто вечно воюет с размером собственных программ. Все сказанное в этом абзаце не относится к резидентным программам.

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


Механизм действия этих процедур следующий. Пусть переменная P имеет предопределенный тип Pointer, а P1, P2, P3 и P4 объявлены как ссылочные переменные. Пусть текст программы содержит фрагмент

- 203 -

...

New(P1);

New(P2);

Mark(P); { вызов Mark }

New(P3);

New(P4);

...

Release(P); { вызов Release }

...

Перед вызовом процедуры Release куча будет иметь вид, как на рис. 11.4.

Рис. 11. 4

При вызове процедуры Mark в переменную P записалось значение HeapPtr, которое было сразу после размещения P2. Далее были размещены P3 и P4, и указатель HeapPtr передвинулся туда, где он изображен на рис. 11.4.