Выделение памяти для динамических переменных
Одним из наиболее важных моментов использования указателей является распределение динамических переменных в динамически распределяемой области памяти. Borland Pascal предусматривает два способа выделения для указателя памяти: процедура New и процедура GetMem.
Использование New как процедуры
New - это очень простая процедура. После описания перемен- ной-указателя вы можете вызвать процедуру New для выделения пространства в динамически распределяемой памяти для указываемого переменной элемента. Приведем пример:
var IntPointer: ^Integer; StringPointer: ^String;
begin New(IntPointer); { выделяет в динамически распреде- ляемой области два байта } New(StringPointer); { выделяет в динамически распреде- . ляемой области 256 байт } . . end.
Пример 8.2 Распределение динамической переменной с помощью процедуры 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 как функцию или процедуру для выде- ления динамического объекта, то можете добавить необязательный второй параметр, который задает применяемый для инициализации объекта конструктор. В Примере 8.3 первое обращение к New распре- деляет пространство для объекта, но не инициализирует этот объ- ект. Второй вызов выделяет память и вызывает для задания объекта конструктор Init.
type PMyObject = ^TMyObject; TMyObject = object constructor Init; end;
var MyObject, YourObject: PMyObject; begin New(MyObject); { объект не инициализируется } New(YourObject, Init); { вызов Init для инициализации объекта }
end.
Пример 8.3 Создание динамических объектов.
Примечание: Об объектах и их конструкторах рассказыва- ется в Главе 9 "Объектно-ориентированное программирование".