Реферат: Программирование ориентированное на объекты
TYPE Треугольник = POINTER TO Фигура_1
Фигура_1 = RECORD
Сторона_1, Сторона_2, Сторона_3:CARDINAL
END;
Четырехугольник = POINTER TO Фигура_2;
Фигура_2 = RECORD
Сторона_1, Сторона_2, Сторона_3, Сторона_4:
CARDINAL
ЕND
VAR T1, T2: Треугольник; М1, М2: Четырехугольник;
BEGIN NEW(T1);... NEW(M1);... NEW(T2);...
DISPOSE(T1);... DISPOSE(T2); NEW(M2);...
┌───────────────────┐ ─┐
│ WORD │ │
├───────────────────┤ │
│ │ > Свободный фрагмент, ранее
├───────────────────┤ │ использованный под
│ │ │ объект Т1^
├───────────────────┤ ─┘─┐
│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │
├───────────────────┤ │
│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │
├───────────────────┤ > Фрагмент, занятый
│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │ под объект М1^
├───────────────────┤ │
│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │
├───────────────────┤ ─┐─┘
│ │ │
├───────────────────┤ │
│ │ > Свободный фрагмент, ранее
├───────────────────┤ │ использованный под
│ │ │ объект Т2^
└───────────────────┘ ─┘
Иллюстрация построена для момента обработки запроса NEW(M2). В этот момент времени в динамической памяти имеются два свободных фрагмента общим объемом шесть слов, которых достаточно для выполнения запроса на выделение элемента хранения под объект М2^ (т.е. для объекта, на котоpый будет указывать M2), однако фрагментация не позволяет системе выделить память под объект М2^.
Система управления динамической памятью ведет специальный список свободных фpагментов - пул памяти. При возвращении какого-либо элемента хранения, используемого в прикладной программе, в пул свободной памяти может быть реализовано "склеивание" соседних свободных фpагментов в один фpагмент большего объема. Например, если в предыдущей программе изменить последовательность обращений к динамической памяти на приведенную ниже, то описанного выше отказа по памяти не произойдет:
BEGIN NEW(T1);...NEW(T2);...NEW(M1);...
DISPOSE(T1);...DISPOSE(T2);... NEW(M2);...
Здесь при обработке запроса NEW(M2) в пуле динамической памяти будет находиться один свободный фрагмент объема шесть слов, образованный "склеиванием" элементов Т1^ и T2^, выполненным при обработке запроса DISPOSE(T2). В общем случае вопросы эффективной реализации управления динамической памятью, обеспечивающей минимум отказов при ограниченном объеме, составляют отдельную проблему. Здесь мы только заметим, что с организацией выделения "первого подходящего" фрагмента памяти в программировании связывают такие термины как "хип" или "куча", относящиеся скорее к профессиональному жаргону, чем к научно-методической терминологии. Тем не менее эти термины довольно образно характеризуют принципы организации динамической памяти.
Организация корректной последовательности запросов связана, кроме того, как минимум еще с двумя проблемами. На том же жаргоне их называют проблемы "висячих ссылок" и "мусора", а определяют они две стороны одной и той же ошибки, заключающейся в некорректной работе с указателями. Следующий фрагмент программы иллюстрирует возникновение таких ошибок (тип "Треугольник" описан выше).
VAR T1, T2:Треугольник;
BEGIN NEW(T1);...T2:=T1;...
DISPOSE(T1); (* T2-"висячая ссылка" *)
............
NEW(T1);...NEW(T2);...
T1:=T2; (* Остался "мусор" *)
Из этого примера понятно, что "висячая ссылка" - это указатель прикладной программы, указывающий на свободный фрагмент динамической памяти. Поскольку этот фрагмент может быть выделен системой по какому-либо запросу другой прикладной программе, Т2 может открыть доступ к "чужим" данным и "разрешить" их интерпретацию как треугольника. Последствия такой интерпретации в общем случае непредсказуемы. Заметим, что "висячая" ссылка и "пустая" ссылка (имеющая значение NIL, см. pазд.III) являются совершенно разными понятиями. "Мусор" - это занятый фрагмент динамической памяти, к которому в прикладной программе потерян доступ. В приведенном примере мусором оказался старый треугольник Т1^, на который указывал Т1 до передвижки (установки на Т2). Этот мусор неустраним: программист не имеет к нему доступа, а система управления "считает" мусор занятым фрагментом памяти.
Объединяет эти два вида ошибок одно общее обстоятельство: они не обнаруживаются исполнительной средой. Идентифицировать подобные ошибки можно только путем тщательной проверки и отладки программы. И, наконец, по своим возможным влияниям на работу программы мусор гораздо "безобиднее" висячей ссылки. Он фактически приводит только к увеличенному расходу памяти, в то время как висячая ссылка способна при определенных условиях полностью парализовать процесс выполнения программы. В сложных системах "цена" висячей ссылки может оказаться очень высокой.
Использование автоматической памяти связано с созданием / уничтожением специальных элементов хранения, связанных с активными объектами - действиями или процедурами. Любая процедура тpебует для выполнения собственной индивидуальной локальной среды. Подобную среду образуют локальные переменные, объявленные в процедуре, формальные параметры, элемент хранения адреса возврата в процедуру, т.е. набор объектов, обеспечивающих выполнение действий, связанных с процедурой. Необходимость в локальной среде возникает только в момент вызова процедуры - момент интерпретации объекта процедурного типа. После завершения такой интерпретации необходимость в локальной среде исчезает. Таким образом, время жизни локальной среды ограничивается временем отработки программы, в которой она описана. Соответственно запрос на создание локальной среды связан с вызовом процедуры, а запрос на уничтожение - с окончанием фазы активности объекта (оператор RETURN или END в теле процедуры). Например:
VAR W1, W2: PROC;
PROCEDURE Работа_1;
VAR A: INTEGER;... BEGIN... W2;...
END Работа_1;
PROCEDURE Работа_2;
VAR A: INTEGER;... BEGIN... W2;...
END Работа_2;
BEGIN... W1:=Работа_1;... W2:=Работа_2;... W1;...
В этом фрагменте описаны два активных объекта процедурного типа PROC = PROCEDURE(): W1 и W2 и две процедуры без параметров: Работа_1 и Работа_2, которые могут использоваться как константы типа PROC. Интерпретация (активизация) W1 приведет к вызову Работы_1 и созданию локальной среды (содержащей переменную А). В процессе выполнения Работы_1 производится активизация объекта W2 и соответственно создание локальной среды для Работы_2. В любой текущий момент времени в системе могут быть активны несколько объектов. (В этом примере активизация W1 приводит к активизации W2, затем они оба остаются в активном состоянии и затем теряют свою активность в обратной последовательности: сначала пассивируется W2, затем W1). Последовательность активации и пассивации связана с вложенностью вызовов процедур, соответственно управление автоматической памятью основывается на использовании стека - структуры, поддерживающей такую вложенность. Ниже для этого фрагмента приведена иллюстрация распределения автоматической памяти, существующего в течение совместной активности объектов W1 и W2.
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11