Пример 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 становится неопределенным.