Элементы ЯПВУ. УКАЗАТЕЛИ. C / С++Pascal Вся динамическая память в Pascal это сплошной массив байтов (куча). Адрес начала кучи храниться в переменной HeapOrg, адрес конца в HeapEnd, а текущую нижнюю границу свободной динамической памяти адресует указатель HeapPtr. Создаваемые в этой памяти динамические переменные не имеют собственных имен – к ним обращаются через указатели. При завершении программы используемая её динамическая память автоматически освобождается, но программист может освободить её до окончания программы. Динамические переменные 1 ВМП
Для выделения памяти типизирован- ному указателю служит стандартная процедура new(): New (P); где P – имя указателя; [new можно исп. и в виде функции] Но для указателя типа Pointer исп.: Getmem (P; Size); где Size - к-во байт памяти. За одно обращение к куче getmem может зарезервировать байт памяти. Для освобождения памяти, выделенной процедурой (функцией) new(), исп.: Dispose (P); От getmem освобождает память Freemem (P; Size); После освобождения памяти значение указателя становится неопределенным, поэтому во избежание проблем его лучше сразу же "обнулить": dispose(p); p:= nil; Элементы ЯПВУ. УКАЗАТЕЛИ. C / С++Pascal Динамические переменные 2 ВМП
Элементы ЯПВУ. УКАЗАТЕЛИ. C / С++Pascal Динамические переменные Для освобождения памяти одновременно из-под нескольких переменных применяют процедуры: Mark (P); она вызывается до начала выделения памяти и записывает в указатель P адрес начала динамической памяти (из переменной HeapOrg). Затем можно процедурой Release (P); освободить участок памяти занятый до момента вызова release, начиная с адреса записанного в mark. Вспомогательные функции: Maxavail – длина в байтах самого длинного свободного участка памяти (тип функции longint), Memavail – полный объем свободной динамической памяти в байтах (тип функции longint), Sizeof (X) – объем в байтах занимаемый X, где X – либо имя переменной любого типа, либо имя типа (тип функции word). 3 ВМП
Элементы ЯПВУ. УКАЗАТЕЛИ. C / С++Pascal Указатели на процедуры и функции Указатели на подпрограмму являются переменной процедурного (функционального) типа: Имя функции (процедуры) – это константа процедурного типа, поэтому присваивание происходит без операции взятия т.к. в этом типе имя подпрограммы - и есть адрес точки входа в неё. type fun = function (x : real) : real; var pf : fun; (* конкретная функция *) function f (x : real) : real : far; Begin ……………………… (* тело функции *) End; pf := f; В переменной pf теперь содержится адрес точки входа в функцию f, и можно вызывать её так: y := pf(x); Функция должна компилироваться в режиме дальней адресации - far, ведь адрес должен содержать сегмент и смещение, а без far – одно смещение, т.к. компилятор формирует всего один сегмент кода. 4 ВМП
Элементы ЯПВУ. УКАЗАТЕЛИ. C / С++Pascal Примеры: Определите что делает программа Program memo; Type mas_int = array [1..maxint] of integer; Var p : ^mas_int; i, n : integer; Begin Writeln ('Введите размер массива:'); Readln (n); If Maxavail < n * Sizeof (integer) then Begin writeln(' Недостаточно памяти'); halt; (*немедленно завершает выполнение программы *) End; Getmem (p, n * Sizeof (integer)); for I := 1 to n do read (p^[i]); End. Эта программа вводит массив целых чисел, размер которого неизвестен на стадии компиляции, а запрашивается во время выполнения программы. Перед выделением памяти проверяется наличие свободного места. 5 ВМП