Lektsia_po_programmirovaniyu_-_11.pptx
- Количество слайдов: 16
Динамическая память. Работа с указателями. Организация элементарных структур на основе динамически выделяемой памяти. Лекция 12
Динамическая память Динамическое распределение памяти — способ выделения оперативной памяти для объектов в программе во время выполнения программы. При динамическом распределении памяти объекты размещаются «куче» (heap): указывается размер запрашиваемой под объект памяти, в случае успеха, выделенная область памяти, условно говоря, «изымается» из «кучи» , становясь недоступной при последующих операциях выделения памяти. освобождение занятой ранее под какой-либо объект памяти: освобождаемая память возвращается в «кучу» и становится доступной при дальнейших операциях выделения памяти. В идеальной ситуации программа должна полностью освободить всю память, которая потребовалась для работы.
Указатель – переменная, которая в качестве своего значения содержит адрес байта памяти. Типизированный Нетипизрованный type massiv=array [1. . 2500] of real; var a: ^integer; b: ^real; d: ^massiv; var p, c, h: pointer; var Some. Number: Integer; pi: ^Integer; pi: =@Some. Number ; p: =Addr(Some. Number);
Переменные кучи
Выделение памяти с помощью NEW(), освобождение DISPOSE() var i: ^integer; r: ^real; begin new(i); new(R); Dispose(i); Dispose(r); end; Разыменование переменной i^: =4+3; r^: =2 * pi; r^: =sqr(r^)+sin(r^+i^)-2. 3; r: =sqr(r^)+i^; r^: =sqr(r); недопустимо
Пример применения разыменования type PInteger = ^Integer; var Some. Number: Integer; Some. Address: Pinteger; begin Some. Number : = 17; Some. Address : = @Some. Number; Writeln(Some. Number); Writeln(Some. Address^); Another. Address : = Some. Address; Anotehr. Address^ : = 99; Writeln(Some. Number); end.
Работа с динамической памятью с помощью процедур getmem и freemem getmem(p, size); где р – указатель, size – размер в байтах выделяемого фрагмента динамической памяти (size: word), резервирует за указателем фрагмент динамической памяти требуемого размера. freemem(p, size); где р – указатель, size – размер в байтах освобождаемого фрагмента динамической памяти, возвращает в кучу фрагмент динамической памяти, который был зарезервирован за указателем.
Найти максимальный и минимальный элементы массива X(N) type massiw= array[1. . 150]of real; var x: ^massiw; i, n: integer; max, min: real; Begin new(x); writeln('Введите размер массива'); readln(n); for i: =1 to N do begin write('x(', i, ')='); readln(x^[i]); end; max: =x^[1]; min: =x^[1]; for i: =2 to N do begin if x^[i] > max then max: =x^[i]; if x^[i] < min then min: =x^[i]; end; writeln('максимум=', max: 1: 4, ' минимум=', min: 1: 4); dispose(x); end. type massiw=array[1. . 150]of real; var x: ^massiw; i, n: integer; max, min: real; Begin writeln('Введите размер массива'); readln(n); getmem(x, n*sizeof(real)); for i: =1 to N do begin write('x(', i, ')='); readln(x^[i]); end; max: =x^[1]; min: =x^[1]; for i: =2 to N do begin if x^[i] > max then max: =x^[i]; if x^[i] < min then min: =x^[i]; end; writeln('максимум=', max: 1: 4, ' минимум=', min: 1: 4); freemem(x, n*sizeof(real)); end.
При работе с динамическими переменными необходимо соблюдать следующий порядок работы: 1. Описать указатели. 2. Выделить память под данные (функции new или getmem). 3. Обработать динамические данные. 4. Освободить память (функции dispose или freemem).
Общие проблемы использования указателей разыменование неинициализированных указателей (nil); var Item. Pointer: Pointer; function Find. Item: Pointer; begin { найти элемент, возвращая указатель на него или nil, если элемент не найден } end; begin Item. Pointer : = nil; { начнем в предположении nil } Item. Pointer : = Find. Item; { вызвать функцию } if Item. Pointer <> nil then Item. Pointer^: =… end.
Общие проблемы использования указателей потери динамически распределяемой памяти ("утечки"). uses heaptrc; var p, Int. Pointer: ^Integer; begin New(Int. Pointer); New(p); Int. Pointer: =p; Dispose(Int. Pointer); Dispose(p); end.
Организация динамических структур. type pzap=^zap; zap=record inf : integer; {информационное поле } next : pzap; {ссылочное поле } end; nil
Процедуры работы с линейным однонаправленным списком type plist = ^list; list=record info : integer; next : plist; end; var first, p: plist; procedure Create_Empty_List ( var first : plist); begin first: = nil; End; procedure Create_New_Elem(var p: plist); begin New (p); Writeln (‘введите информационное поле: '); Readln (p^. info ); p^. next : = nil; end; function Count_el(First: plist): integer; Var K : integer; cur : plist; begin If First = Nil then k: =0 Else begin k: =1; cur: =First; while cur^. Next <> Nil do begin k: =k+1; cur: =cur^. Next; end; Count_el: =k; end;
procedure Ins_after_I ( first, p : plist; i : integer); var temp , cur : plist; K , n : integer; begin n : = count_el(first); if (i < 1 ) or ( i > n )then begin writeln ('i не корректно'); exit; end else begin Create_New_Elem(p); if i = 1 then begin cur : = first; temp : = cur^. next; cur^. next : = p; p^. next : = temp; end else if i = n then begin cur: =First; while cur^. Next <> Nil do cur: =cur^. Next; cur^. Next: =p; P^. Next: =Nil; end Else begin cur : = first; for k: =2 to i do cur : = cur^. next; temp : = cur^. next; cur^. next : = p; p^. next : = temp; end;
procedure Delete_List(Var First : plist); Var temp, cur : plist; begin If First <> Nil Then begin cur: =first^. next; while (cur <> nil ) do begin temp: =cur; cur: =cur^. Next; Dispose(temp); end; dispose(First); first: =nil; end else writeln (‘список пуст '); end; begin p: =nil; Create_Empty_List (first); Create_New_Elem(p); first: =p; Ins_after_I ( first, p, 1); Delete_List( First); end.
Lektsia_po_programmirovaniyu_-_11.pptx