Динамические переменные создаются в хипе (куче, динамической памяти) во время выполнения программы с помощью процедур new и getmem. Они не имеют собственных имен – обращаются к ним через указатели.
Динамические переменные – это переменные, созданием и уничтожением которых управляет программист. Работа с динамической областью памяти в TURBO PASCAL реализуется с помощью процедур и функций New, Dispose, GetMem, FreeMem, Mark, Release, MaxAvail, MemAvail, SizeOf.
· New(указатель);- процедура, благодаря которой в динамической памяти выделяется участок размера, достаточного для размещения переменной того типа, на который ссылается указатель, и адрес начала этого участка заносится в этот указатель.
· New(указатель); -функция, которая выделяет в динамической памяти участок размера, достаточного для размещения в ней переменной, и возвращает адрес начала этого участка.
Функция и процедура new применяются для типизированных указателей.
· Getmem(указатель, размер в байтах)-процедура, которая выделяет в динамической памяти участок указанного размера (не более 64 Кб) и присваивает адрес его начала указателю. Эту процедуру можно применять и для указателей типа pointer.
После выполнения процедур: new(P1); new(P2); new(P3); new(P4); new(PМ); в динамической памяти выделяются участки для размещения данных и ссылочным переменным P1, P2, P3, PM присваиваются указатели на эти участки памяти.
У динамических переменных имени (идентификатора) нет, поэтому прямое обращение к такой переменной просто невозможно. Единственный способ, это косвенное обращение путем разыменования ссылочной переменной, содержащий указатель на данную динамическую переменную, например: P1^:=15, P2^:=-150.
Для освобождения динамической памяти используются процедуры Dispose (если память выделялась с помощью new) и Freemem (если память выделялась с помощью getmem).
· Dispose(указатель) – процедура, которая освобождает участок памяти, выделенной для размещения динамической процедурой или функцией new, а значение указателя становится неопределенным.
· Freemem(указатель, размер) – процедура, освобождающая участок памяти указанного размера, начиная с адреса, находящегося в указателе. Значение указателя становится неопределенным.
Пример 1. Рассмотрим пример работы с динамическими переменными.
P:=D; {указатели P и D стали ссылаться на одну и ту же величину,
равную 3}
Writeln(P^, D^);{дважды напечатается число 3}
При работе с динамической памятью часто применяют следующие вспомогательные функции:
· Maxavail – возвращает длину в байтах самого длинного свободного участка динамической памяти.
· Memavail – возвращает в байтах полный объем свободной динамической памяти.
· Sizeof(x) – возвращает в байтах объем памяти, занимаемой x ( под x подразумевается переменная любого типа, либо имя типа).
Пример 3. Заполнить одномерный массив псевдослучайными числами и вывести их на экран.
В этом примере используется процедура getmem и функции, описанные выше.
Program memory;
Uses crt;
Type
mas_int=array[1..maxint] of integer; {maxint=32767}
Var
p:^mas_int; {указатель на одномерный массив}
i,n:integer;
Begin
clrscr;
writeln(sizeof(integer)); {определяем размер типа integer}
writeln(maxavail, ' ',memavail); {определяем значение этих функций}
writeln('Введите размер массива: ');
readln(n);
if maxavail<n*sizeof(integer) then
Begin
writeln('Недостаточно памяти');
halt;
end;
getmem(p,n*sizeof(integer));
for i:=1 to n do
Begin
p^[i]:=random(100);
write(p^[i]:3);
end;
readkey; end.
Пример 4. Создать вещественный массив из 10000 чисел, заполнить его псевдослучайными числами в диапазоне от 0 до 1. Вычислить среднее значение массива. Очистить динамическую память. Создать целый массив размером 10000, заполнить его псевдослучайными числами в диапазоне от -100 до 100. Вычислить среднее значение массива и очистить динамическую память.
Program Ykazatel;
Uses crt;
Type
masint=array[1..10000] of integer;
masreal=array[1..10000] of real ;
Var
PInt:^masint;
PReal:^masreal;
i:word;
sum,sred_real,sred_int:real;
Begin
randomize;
new(PReal); {выделение памяти под вещественный массив}