Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2012 02 26 Основы программирования в Delphi.docx
Скачиваний:
4
Добавлен:
16.08.2019
Размер:
204.56 Кб
Скачать

Размещение динамических переменных

Выделение динамической памяти в программе на Object Pascal осуществляется с помощью специальных подпрограмм. К ним относятся функции AllocMem, GetMem и New. Функция AllocMem реализует наилучший метод динамического размещения с очисткой выделенной памяти. Обратимся к примеру с записью типа TMailingListRecord. В том примере переменная MLRecord является статической и, следовательно, размещается в стеке:

var

MLRecord : TMailingListRecord;

begin

{ Заполнить MLRecord данными. }

MLRecord.FirstName := 'Per';

MLRecord.LastName := 'Larsen';

{ и т.д. }

end;

Теперь воспользуемся динамической переменной:

var

APtr : PMailingListRecord;

begin

APtr := AllocMem(SizeOf(TMailingListRecord));

APtr.FirstName := 'Per';

APtr.LastName := 'Larsen';

{ . . . . . . . . . . . }

FreeMem(APtr);

end;

Здесь мы объявили переменную APtr типа PMailingListRecord, которая является типизированным указателем на запись типа TMailingListRecord. Таким образом, в стеке программы появится переменная APtr, значением которой будет адрес участка динамической памяти, выделяемой в результате обращения к функции AllocMem. Параметром в обращении к этой функции является количество байт, определяющее размер участка динамической памяти. Здесь размер памяти вычисляется с помощью функции SizeOf. В результате обращения к AllocMem в куче создается экземпляр динамической переменной типа TMailingListRecord. Далее мы можем обращаться к полям записи как обычно.

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

Итак, мы рассмотрели правила, связанные с понятием «динамическая переменная». Использовать в программах такие динамические переменные или нет – решает программист. Однако, что касается объектов – представителей классов объектно–ориентированного программирования, то они могут быть только динамическими.

ПРИМЕЧАНИЕ: Пустое значение указателя обозначается ключевым словом nil. Например, проверить связан ли указатель с динамической памятью или нет можно так:

if SomePointer = nil then SomePointer := AllocMem(Size);

Разыменование указателя

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

Новый термин: «Разыменовать» указатель означает «получить доступ» к тому объекту, на который он указывает.

Обратимся к примеру с записями типа TMailingListRecord:

var

APtr : PMailingListRecord;

Rec : TMailingListRecord;

begin

APtr := AllocMem(SizeOf(TMailingListRecord));

Допустим, что нам необходимо скопировать данные динамической переменной APtr в статическую переменную Rec. Переменная APtr есть указатель на TMailingListRecord, в то время как Rec является переменной типа TMailingListRecord. Поэтому следующее выражение вида Rec := APtr; некорректно, ибо APtr содержит адрес памяти, а не значения полей записи TMailingListRecord. Чтобы решить рассматриваемую задачу, указатель надо разыменовать. Для этого используется специальный символ разыменования указателя (^):

Rec := APtr^;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]