Выделение блока памяти

Для организации динамических структур данных в качестве базовых элементов используются ссылочные указатели, при этом в динамической памяти (кучи) выделяются блоки памяти, необходимого размера, адреса которых хранятся в ссылках или указателях, связанных с этими блоками.

Для выделение памяти под динамические переменные используется функция NEW(<параметры>); (часто используются как процедура). Параметром этой функции являться ссылочная переменная на некоторый базовый или пользовательский тип данных. Данный тип определяет размер выделенного блока, адрес начала этого блока будет записан в ссылочный переменную параметр.

Пример выделение динамической памяти:

Var

I:byte;

P1,p2:^integer;

P3:^REAL;

Begin

{1}

I:=5;

New(p1);

New(p2); {2}

New(p3);

В данном случае после выполнения трех операторов NEW в динамической памяти последовательно выделятся два блока по два байта и один блок под шесть байт (реально выделенный объем будет несколько иным, смотри предопределенные указатели).

Адреса этих выделенных блоков будут находиться в ссылочных переменных Р1, Р2, Р3 соответственно. Последовательное выделение блоков из памяти не всегда означает, что блоки будут располагаться друг за другом, в ряде случаев они располагаются в различных местах памяти на момент выделении блоков. При последовательном выделении блоков, блоки размещаются в сторону увеличение адресов.

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

Пример применения разадрисации: в выделенные блоки помещаем

информацию.

P1^:=10;

P2^:=p1^-4;

I:=p1^;

P3^:=i+p1^+p2^;

Особенностью оператора New является то, что она в большей степени используется с ссылочными переменными, которые указывают необходимый для выделение объем памяти. В этом случае эта функция используется, как однако её можно использовать и при работе с указателями. Для этого устанавливается ссылочный тип данных, который будет использоваться для определения размеров блока.

Пример использования ссылочной переменной.

Type

I_int=^integer;

Var

P:pointer;

.

.

P:=new(i_int);

{$X+} - разрешён обособленный вызов функций т.е как процедур.

При выполнении функции New объем доступной динамической памяти уменьшается, блоки памяти выделенные с помощью этой процедуры считаются администратором кучи занятыми (связанными с некоторыми ссылками) даже если этот блок не заполняется, поэтому повторный запрос на выделение блока с помощью new не может привести к тому, чтобы занятый блок был связан с другой ссылкой или указателем.

 
 


Пример:

New(p1);

New(p2);

Р1- считается занятым если даже ничего там не записано.

1) Процедура освобождения памяти

Dispose (<ссылка>)

Данная процедура используется для работы с типизированными ссылочными переменными, является парной функции New, оказывает противоположенное ей действие, связанное с освобождением блока памяти, тип ссылки указывает блок какого размера необходимо освободить. Адрес освобождаемого блока находиться переменной. После выполнения данной процедуры оббьем доступной памяти увеличивается.

Пример:

Var

P1:^integer;

.

{1}

 
 


New(p1);

P1^:=5; {2}

Dispose(p1);{3}

HeapPtr - Предопределенный указатель, который содержит адрес нижней границы свободной области кучи. Считается что после выполнения процедуры Dispose блок памяти связанный с ссылочной переменной-параметром данной процедуры удаляется из памяти, при этом ссылочная переменная считается неопределенной и поэтому если необходимо воспользоваться ею выполняется операция её инициализации каким-либо адресом (new(p1)). Фактически после выполнения процедуры Dispose блок связанный с ссылочной переменной считается свободным. Он в любой момент времени может быть занят администратором кучи при запросе на выделение блока. Объём доступной динамической памяти увеличивается, данные находящиеся в блоке не удаляются, ссылка остается определена тем же адресом (но лучше её считать неопределенной).

Пример: выделение и заполнения динамических блоков.

Var

P1,p2:^integer;

.

.

New(p1);

P1^:=5;

Dispose(p1);

New(p2);

P2^:=10;

Write(p1^);

После выполнения команды Write(p1^); выведет на экран значение 10;

2) выделение блока памяти из кучи

Для этого используется еще одна процедура GetMem (<параметр1>,<параметр2>);

Параметр1 –это ссылка или указатель

Параметр2-значение типа word определяющее размер выделяемого блока.

Адрес выделяемого блока будет храниться в параметре1.

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

Пример: выделение памяти с помощью процедуры GetMem.

Var

P:pointer;

.

.

Getmem(p,sizeof(real));

Getmem(p,1024);

Реально выделенный объем будет другим.

Пример работы с блоками памяти.

Var

P:^byte;

.

.

Getmem(p,4);

P1^:=300; больше чем байт!

P^:=3; - это сработает;


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: