Пример 41

Операции с указателем

Выделение и освобождение динамической памяти

Создание и уничтожение динамических переменных реализуется стандартными процедурами New и Dispose.
Для выделения области памяти под значение динамической переменной используется процедура New. Вызов процедуры:

New( < имя_указателя >);

Например, выполнение процедуры

New( IDin1);

создает новую динамическую переменную IDin1^, указатель IDin1 содержит адрес этой переменной. Размер выделяемого участка памяти определяется типом указателя. В данном случае он равен двум байтам (тип Integer). Теперь возможно присвоить новой динамической переменной значение:

IDin1^ := 123;

Для освобождения памяти, выделенной под динамическую переменную, используется процедура Dispose. Вызов процедуры:

Dispose( < имя_указателя >);

Например, в результате выполнения процедуры

Dispose( IDin1 );

память, связанная с указателем IDin1, будет отмечена как свободная. Соответствующая динамическая переменная IDin1^ уничтожается.

Значением указателя является адрес, поэтому число допустимых операций ограничено. Указателям можно присваивать значения адреса либо процедурой New, либо оператором присваивания, в правой части которого содержится указатель того же ссылочного типа, например:

New(IDin2);

Указателю IDin2 присвоен конкретный адрес памяти динамической переменной IDin2^.

IDin3 := IDin2;

После выполнения этого оператора оба указателя будут содержать адрес одной и той же области памяти.
Любому указателю можно присвоить значение специальной константы NIL, например:

IDin2 := NIL;

Такой указатель называется пустым, т.е. не указывает ни на какую переменную. Указатель со значением NIL содержит 0 в каждом из четырех байтов.

Указатели можно сравнивать между собой и с константой NIL, например:

if IDin2 = IDin3 then IDin2^ : = IDin2^+1; if IDin3 <> NIL then IDin3^ : = 12.5;

Сравнение указателя с константой NIL позволяет установить, существует ли для него динамическая переменная. Если указатель равен NIL, то для него не существует динамической переменной.
Пример поясняет использование указателей и связанных с ними динамических переменных.

 

1. var I1,I2: ^integer;

Объявлены два указателя на динамические переменные целого типа. Компилятор выделяет две области памяти для хранения адресов - значений указателей I1, I2,которые пока не определены.

2. I2 := NIL;

Указателю I2 присваивается значение константы NIL.

3.New(I1);

Выделяется область памяти для динамической переменной I1^, адрес этой области A1 присваивается указателю I1.

4. I1^ := 12;

Динамической переменной I1^ присваивается значение 12.

5. I2 := I1;

Указателю I2 присваивается тот же адрес, что и в I1, в результате появилась возможность доступа к области памяти, содержащей 12, как по имени I1^, так и по имени I2^.

 

6. I2^ := I1^ + 1;

Значение переменной I1^, I2^ увеличивается на 1.

7. New(I1);

Для динамической переменной I1^ выделяется новая область памяти по адресу A2, который присваивается указателю I1.

8. I1^ := 23;

Динамической переменной I1^ присваивается значение 23.

9. I2^ := I1^ + 1;

Динамической переменной I2^ присваивается новое значение 24.

10. Dispose(I1);

Уничтожается динамическая переменная I1^, память освобождается, значение указателя I1 становится неопределенным.