Динамическая память
Динамические структуры – это структуры данных с изменяющимися в процессе работы программы размерами. Такие структуры можно по ходу программы создавать и удалять. Эти данные запоминаются в динамической памяти (ДП). В ДП операционной системой выделяется область (куча). Для динамических структур используются переменные типа-указатель (или указатель). Указатель содержит адрес первого байта переменной в ДП. Длина переменной определяется ее типом. Тип-указатель должен быть объявлен. Если тип объекта, на который ссылается указатель не стандартный, то его нужно объявить до применения указателя. Затем необходимо объявить указатели.
Свойства указателей
Указатель – носитель физического адреса в памяти величины базового типа. Указатель имеет размер в 2 слова (4 байта). Создается компилятором в статической памяти.
Адрес=<Сегмент>*16+<Смещение>
Для указателей, ссылающихся на объекты разного типа, недопустима операция присвоения. Указатели на объекты одинакового типа можно сравнивать друг с другом. Примеры
x:=p^;
p^:=x;
Можно использовать операцию @:
program DinamPamyath;
{$mode objfpc}{$H+}
uses Classes,SysUtils;
var
b,c:byte;
P1:^byte;
begin
b:=10;
writeln(‘b=’,b);
P1:=@B;
c:=5+p1^;
writeln(‘c=’,c);
readln;
end.
Средства работы с динамической памятью
В модуле System определены средства:
Вызов | Содержание |
New(P) New – создать заново, P – имя указателя. |
Выделить область памяти для величины базового типа, на которую указывает Р. Ее адрес присвоить указателю Р. |
Dispose(P) Dispose – удалить. P – имя указателя. |
Освободить область памяти, на которую указывает Р. После выполнения процедуры Р = nil (неопределенно). |
GetMem(P, Size) Get Memory – получить память, |
Выделить область памяти размером Size. Ее адрес присвоить указателю Р. Используется для резервирования больших фрагментов ДП. |
FreeMem(P, Size) Free Memory – освободить память, |
Освободить область памяти размером Size, на которую указывает указатель Р. После выполнения процедуры Р = nil (неопределенно). |
SizeOf(X) | Возвращает длину в байтах Х. |
Addr(X) | Возвращает адрес Х. |
Работа с динамическими структурами
Пример 1. Создание динамических структур.
program Ukazateli;
{$mode objfpc}{$H+}
uses SysUtils; // Ссылка на модули
type
RecCircle = record // Запись для окружности:
x:integer; // Координата X центра
y:integer; // Координата Y центра
Radius:byte; // Радиус
end;
PointerRecord=^RecCircle; // Тип-указатель на запись (нестандартный)
var
Pointer1:^Real; // Указатель на вещественное число
Pointer2:PointerRecord; // Указатель на запись
begin
{————-}
end.
Пример 2. Работа с динамическими структурами.
program PodprogramDP;
{$mode objfpc}{$H+}
uses SysUtils; // Ссылка на модули
var
p1:^Byte=nil; // Указатели с инициализацией
p2:^Word=nil;
Result:Real;
begin
New(p1); // Выделить ДП под р1
writeln(‘ Razmer p1=’,SizeOf(p1));
writeln(‘ Razmer p1^=’,SizeOf(p1^));
New(p2); // Выделить ДП под р2
writeln(‘ Razmer p2=’,SizeOf(p2));
writeln(‘ Razmer p2^=’,SizeOf(p2^));
readln; // Пауза, смотрю результат
p1^:= 23; // Присвоить значение р1^.
p2^:= 43; // Присвоить значение р2^.
Result:=p1^+p2^; // Операция с р1^ и р2^.
writeln(‘p1^=’,p1^); // Вывод данных
writeln(‘p2^=’,p2^);
writeln(‘Result=’,Result:5:2);
Dispose(p2); // Освободить ДП под р2
p2:= nil; // Указатель p2 пуст
Dispose(p1); // Освободить ДП под р1
p1:= nil; // Указатель p1 пуст
readln; // Пауза, смотрю результат
end.