Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ОАиП_1 / Module2 / УЭ-11

.html
Скачиваний:
17
Добавлен:
25.02.2016
Размер:
24.49 Кб
Скачать

Документ без названия

Статическое и динамическое распределение памяти. Понятие указателя. Процедуры управления heap-областью. Описание и обработка динамических массивов.       Все переменные, которые описываются в разделе var называются статическими. При выполнении программы каждой такой переменной отводится соответствующее число ячеек памяти, которые закрепляются за переменными на все время работы программы.       Динамические переменные могут создаваться и ликвидироваться по мере необходимости. В процессе работы программы для них выделяется и освобождается память необозначенная именем конкретной переменной. Для работы с этой памятью используются ссылки.    Динамически распределяемая область памяти - это оперативная память компьютера, предоставляемая программе за вычетом памяти, занимаемой самим телом программы, сегментом данных и сегментом стека       Распределение памяти: Верхняя граница   1 FreePtr, находится список записей регистрирующих наличие свободного пространства в динамической памяти 2 HeapPtr, свободная область 3HeapOrg, SSeg, область динамической памяти, которая распределяется начиная с переменной HeapOrg в сторону увеличения адресов; управление распределением ведется через список свободных областей 4Область для загрузки оверлейных программ 5Область памяти для сегмента стека, распределяемая в сторону уменьшения адресов 6 Для хранения глобальных переменных 7DSeg,для типизированных констант 8System,сегмент кода модуля System 9Uses,остальные модули, которые используются в программе 10Uses, остальные модули, которые используются в программе 11Uses, область хранения кода основной программы 12Префикс программного сегмента       Сегмент стека следует за сегментом данных. Значение сегмента стека остается постоянным и возвращается при вызове функции SSeg. Получить значение сегмента данных можно при вызове функции DSeg.       Стек служит для передачи параметров при вызове процедур и функций. В нем на протяжении всего времени выполнения программы сохраняет критические значения, размещает все локальные переменные, а также, за счет использования пространства стека, обеспечивает вложенность процедуры в функции.       Неправильное использование стека может привести к перекрытию сегментов, что приведет к нарушению целостности данных. Чтобы этого не произошло, необходимо четко определять размер рабочего стека программы и обращения к нему. Для этого служит директива {$S} – это директива компилятора, которая определяет отсутствие перекрытий. После отладки программы эту директиву можно убрать.       Объем динамической памяти для программы определяется директивой {$M}.    Общий вид директивы: {$M размер стека, min размер Heap, max размер Heap}                                                 16Кb                   (0)                   (вся свободная память)    Указатель - переменная целого типа, которая интерпретируется как адрес байта памяти, содержащего некоторый элемент данных. Это может быть переменная, константа, адрес другой переменной.       Описание и инициализация указателей:       Var           Num: integer;           Таким образом резервируется область памяти, к которой можно обратиться по имени.           Адрес, по которому находится в памяти эта переменная, можно определить с помощью оператора @:

          P1:=@Num;           Таким образом в Р1 будет записан адрес памяти, по которому находиться переменная Num.       Адрес представляет собой два 16-тиразрядных слова: (ВА:BS) – (сегмент: смещение):

   Сегмент - участок памяти длиной 64 Kb, который начинается с физического адреса, значение которого кратно 16    Смещение - число, которое определяет номер байта в сегменте, к которому необходимо обратиться       Чаще всего указатели применяются в следующих случаях: когда программа должна работать с большими объемами машинных данных если во время компиляции программы используются данные, объем памяти для хранения которых заранее не известен (строки, массивы) если в программе используется буфер памяти для временного хранения данных, т.е. когда нет необходимости сохранять временные данные если программа работает со ссылочными типами данных если программа использует динамические структуры данных       Указатели бывают: типизированные (связаны с некоторым типом данных)       Var           P:^ integer;     {объявление указателя на значение целого типа}       В некоторых случаях указатели могут ссылаться на еще необъявленные типы данных:       TYPE           P1P=^ integer;       Var           P1:^ integer;       Это дает возможность организовать хранение данных в виде списка, каждый элемент которого содержит указатели на следующий и предыдущий элементы и позволяет легко находить необходимые данные нетипизированные (не связаны с определенным типом данных)       Var           P2:pointer;       Эти указатели используются для динамического размещения данных, структура и тип которых изменяются в ходе выполнения программы.       Для указателей допустимы только операции сравнения и присваивания.       Указателю можно присвоить: содержимое другого указателя, имеющего тот же тип константу NIL – пустой указатель адрес памяти, определенный с помощью оператора @ адрес возвращаемый функцией PTR       Пример 1.       Var           P1, P2:^ integer;           …           Num: integer;       Begin           P1:= NIL;           P1:= P2;           P2:= @ Num;           …           Num^:=7;       Существует два основных метода работы с динамически распределяемой областью памяти: с помощью процедур New, Dispose с помощью процедур GetMem, FreeMem       Вся динамическая память может рассматриваться как массив состоящий из байтов. Heap область размещается в памяти компьютера за область памяти, которую занимает тело программы. Для работы с динамической памятью существует ряд стандартных переменных: Переменная Назначение HeapOrg Cтандартная переменная-указатель – является нижней границей динамической памяти и содержит абсолютный адрес начала динамической памяти. HeapEnd Cтандартная переменная-указатель для верхней границы HeapPtr Cтандартная переменная-указатель содержит текущее значение указателя, разделяет занятую и свободную части Heap-области. В зависимости от выделения или освобождения памяти система передвигает указатель HeapPtr вверх или вниз. FreePtrХранит адрес нижней границы участка памяти, расположенного в верхних адресах DOS. Этот участок содержит список записей, регулирующих наличие свободной памяти в Heap-области. Каждая запись этого списка содержит всю информацию о размещении соответствующей динамической переменной в памяти.       Пример 2. Процедура создает новую динамическую переменную того типа, на который ссылается указатель и устанавливает указатель таким образом, чтобы он указывал на эту переменную.       Var           P1:^ integer;           P2:^ string;       …       Begin           New(P1);           New(P2);       …       Пример 3. Значением любого указателя является адрес. Чтобы получить доступ к данным по этому адресу:       Var           P1, P2:^ integer;       …       Begin           New(P1);           New(P2);           P1^:= 7; P2^:= 7*2;       Над динамически распределяемыми данными можно производить различные операции:       Пример 4.       P1^:= 2*P2^+(P2^-3)*3;       Нельзя присвоить указателю значение или значению указатель:       Пример 5. Так нельзя:       P1:= 5*P2^       P1^:=P2    Динамический массив - массив, размер которого может меняться во время исполнения программы Объявление ИнициализацияПример     Type         Mas= Array [1..1000] of integer;     Var         P:^ Mas; {P – указатель на динамический массив, который описан типом Mas}     …     For i:= 1 to 1000 do         Begin             P^[i] := I;             Write (P^);         end;     Cоздать вещественный массив из 10000 чисел, заполнить его случайным образом. Вычислить среднее значение массива, очистить память. Тоже сделать для массива из целых чисел     Type         MasInt = array [1..10000] of integer;         MasReal = array [1..10000] of real;     Var         Pint: ^ MasInt; PReal: ^ MasReal;         I, mid: longiht;         Midr: real;     Begin         Midr:= 0; mid:= 0;         Randomize;         New(Preal);             For i:= 1 to 10000 do                 Begin                     Preal^[i]:= Random;                     Midr:= midr+Preal^[i];                 End;         Dispose(Preal);         New(Pint);             For i:=1 to 10000 do                 Begin                     Pint^[i]:= random(2100)-100;                     Mid:= mid+Pint^[i];                 End;         Dispose(Pint);         Writeln ('Среднее целое', mid div 10000);         Writeln ('Среднее вещественное', midr div 10000);     End.

Соседние файлы в папке Module2