Одним из наиболее важных моментов использования указателей является распределение динамических переменных в динамически распределяемой области памяти. Borland Pascal предусматривает два способа выделения для указателя памяти: процедура New и процедура GetMem.
Использование New как процедуры
New - это очень простая процедура. После описания переменной-указателя вы можете вызвать процедуру New для выделения пространства в динамически распределяемой памяти для указываемого переменной элемента. Приведем пример:
var IntPointer: ^Integer; StringPointer: ^String;
begin New(IntPointer); { выделяет в динамически распреде- ляемой области два байта } New(StringPointer); { выделяет в динамически распреде- . ляемой области 256 байт } . . end.
Пример 1. Распределение динамической переменной с помощью процедуры New.
После вызова процедуры New переменная-указатель указывает на память, выделенную в динамически распределяемой памяти. В данном примере IntPointer указывает на двухбайтовую область, выделенную процедурой New, а IntPointer^ - это допустимая целочисленная переменная (хотя это целочисленное значение еще не определено). Аналогично, StringPointer указывает на выделенный для строки 256-байтовый блок, а его разыменование дает доступную для использования строковую переменную.
Использование New как функции
Кроме выделения памяти для конкретной динамической переменной вы можете использовать New как функцию, возвращающую указатель конкретного типа. Например, если PInteger - это тип, определенный как ^Integer, а IntPopinter имеет тип PInteger, то следующие два оператора эквивалентны:
New(IntPointer); IntPointer := New(PInteger);
Это особенно полезно в случаях, когда может потребоваться присваивать переменной-указателю элементы различных типов. Иногда желательно распределять динамическую переменную, не присваивая явно указатель конкретной переменной. Вероятно, вы можете сделать это только создав для процедуры и функции параметр:
SomeProcedure(New(PointerType));
В этом случае SomeProcedure будет добавлять передаваемый параметр к некоторому списку. В противном случае распределяемая память будет потеряна. Библиотеки Borland Turbo Vision и Borland Pascal широко используют этот метод для присваивания динамических объектов спискам.
Использование New с объектами
Когда вы используете New как функцию или процедуру для выделения динамического объекта, то можете добавить необязательный второй параметр, который задает применяемый для инициализации объекта конструктор. В Примере 2 первое обращение к New распределяет пространство для объекта, но не инициализирует этот объект. Второй вызов выделяет память и вызывает для задания объекта конструктор Init.
type PMyObject = ^TMyObject; TMyObject = object constructor Init; end;
var MyObject, YourObject: PMyObject; begin New(MyObject); { объект не инициализируется } New(YourObject, Init); { вызов Init для инициализации объекта }
end.
Пример 2. Создание динамических объектов.
Освобождение памяти, выделенной для динамических переменных
Память, распределенная для переменных с помощью New, после завершения работы с ними должна освобождаться. Это позволит использовать динамически распределяемую память для других переменных. Чтобы освободить память, выделенную для динамической переменной, вы должны использовать процедуру Dispose. В Примере 1 вы можете добавить следующее:
Dispose(StringPointer); Dispose(IntPointer);
Нужно помнить, что если вы распределяете динамические переменные с помощью New, то освобождать выделенную для них память после завершения работы с этими переменными нужно с помощью Dispose.
8 8 8
|