Программирование ориентированное на объекты
Фигура_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.
┌─ ┌───────────────────┐ ─┐
│ │ Переменная А │ │
│ ├───────────────────┤ > Локальная среда
│ │ Адрес возврата │ │ для W1
Занятое прост- < ├───────────────────┤ ─┤
ранство │ │ Переменная А │ │
│ ├───────────────────┤ > Локальная среда
│ │ Адрес возврата │ │ для W2
Вершина ──> └─ │───────────────────┤ ─┤
стека │ │ │
автоматической │ │ │
памяти │ │ │ Свободное
│ │ > пространство
Пассивация │ │ │ памяти
│ ^ │ │ │
│ │ │ │ │
│ │ │ │ │
v │ └───────────────────┘ ─┘
Активация
При активации каждого нового объекта вершина стека "опускается вниз" на величину, определяемую размерами локальной среды этого объекта,- при его пассивации вершина стека "поднимается вверх". С использованием автоматической памяти связаны две основные проблемы: рекурсии и множественности ассоциаций.
Рекурсия - механизм, позволяющий объекту совершать самоактивац-ию. Например, по схеме:
W1-->W1 (прямая рекурсия)
или W1-->W2 ...-->W1 (косвенная рекурсия).
Прямая рекурсия связана с непосредственной повторной (вложенной) активацией, а косвенная - с опосредованной (причем число посредников в схеме W1-->...-->W1 может быть произвольным). Использование рекурсии напрямую связано с размерами рабочего пространства автоматической памяти. Использование рекурсивных активаций объектов, с одной стороны, позволяет иметь очень лаконичные и емкие по содержанию программы, с другой стороны, в рекурсивных схемах (особенно в косвенной рекурсии) возрастает вероятность появления трудно идентифицируемых ошибок.
Множественность ассоциаций заключается в том, что в классе автоматической памяти могут быть одновременно размещены несколько одноименных объектов, имеющих в общем случае различные значения и относящиеся к разным активностям одного и того же или опять-таки разных объектов. В приведенном примере существуют два одноименных объекта: переменная А, связанная (ассоциированная) с активностью W1, и переменная А, ассоциированная с активностью объекта W2. В соответствии с принципом стека система упpавления автоматической памятью всегда pассматpивает в качестве активной последнюю созданную ассоциацию (самую "ближнюю" к вершине стека автоматической памяти). Возникновение множественности ассоциаций обусловлено только использованием в прикладных программах одноименных переменных с различной областью действия (областью видимости). Если уж использование таких переменных и является необходимым (в чем всегда стоит усомниться), то при их интерпретации следует помнить о множественности ассоциаций.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄АБvГ ДqU Гm╜ ╛h╤ ¤e└ ╟bе ┬_ Z@ @@ -xо ├sч ■nФ йiз │d└ ╨_w" Ы"ZB# B#C#tj# k#mr# s#fа# б#_Ў# ў#X∙# ·#QН% w" Ы"ЇЇЇЇЇЇ
Н%О%tс& т&m=' >'fP' Q'_0( 1(X3( 4(Qq( w" Ы"ЇЇЇЇЇЇ
q((vк( ┤(q╗* ╩*l/+ N+gS+ T+`я+ ,[, 5,V0 Ї0*0v51 X1qQ9 b9n; у;kO< T 3c5ctУc Фcmf ffg ga▀g щg^ak ikYjkV╪k +T ╪k┘kt l #lo/m 0mh╓p ·pc]q nqaЧq │q_├q Zr]░t ВuZ777 Вupv zvv ТТtэТrмЧ ╦Чp╪Ч ┘ЧnєЧ √ЧlШ 4Шj6Ш `ШhbШ eШfgШ КШd7777777 КШМШ еШyжШ оШw╗Ш ┌Шu█Ш ▀ШsуШ Щq#Щ MЩoOЩ RЩm_Щ ЙЩkНЩ 7777777777НЩ╖Щy╣Щ ╝Щw═Щ ўЩuЪ 2Ъs4Ъ ^Ъq█Ы эЫl╫Э 'Юj-Ю .Юh6Ю 7Юf777777777ЮHЮ IЮyRЮ SЮw]Ю ^ЮuцЮ чЮsыЮ ЇЮq¤Ю ЯoЯ ЯmЯ XЯkZЯ 7777777777ZЯХЯyЧЯ ╥Яw╘Я аuа HаsJа Баqъл мl▒ ╧▒ib┤ n┤fS╢ ZЯ 77777S╢_╢v"╣ A╣qt╣ П╣lp╝ ╝gу┼ х┼`╞ ╞Y╞ ╞Rb┤ ╞╞ ╞tУ╨ ж╨oЯ╪ ╗╪ju▌ Л▌e╬▌ ▐`Y▀ }▀[ф "фX "фAх [хxQц mцsнц ┬цn╪ш тшiшш Єшd#щ :щ_Bщ PщZы ы&ыvОы еыqбь вьo▒ь █ьm э Pёk~ёfzўdвў_] ы 7676777 v c sF pK WmZ fj╠ ┌g+ Cb s]sъ vВ Мq└ сl= hg▀ ! bk Ж ]а# ╢#Zь( ь(є(v5, N,tP, ?0rA0 у1pц1k@i#@d╦Bb┌B]^G[sGVь(676767777sGНGyЧGt╙G Ho║Mm▀MhсMfуMaыM^?N ╪PЄPYСQ SWь(776767667S:SvTtTo)T █Tm▄T сMfуMaыM^?N ╪PЄPYСQ SWь(776767676АГiЖW╔JсJуH╪PЄPYC B!7р<
Ё<" Ёуn:n<l>lL_U]Г[р<
?C B!7рC B!7рГЕnЦkШiЪiЬiЮiаiвiB!7C< B!7рвдyжyиyкyмyоy╝l╜ B!7C B!7рC╜└i╧g╤eUcjcЦc cТcB!ICI
uEu.u╥u═u ЁC?I ═Мy╬wOuпuБu7"cF$aз%aCC
ЁC?Cз%╫%y&yT&yf&yЯ&y▐&yр&y(y∙*y -y?C -?-y╢.yф0yН5yк9y▀:y;wу;uх;uC?C х;?yщ@y&AyУAy·ByлDyУGy▓HyхHyIy?C I IyNyЇSy╘Uy·Uy+Vy[VywVy+WyTWy?C TWXy+XyэZyX[y[y╗[yт[y·[y,y╫]y?C ╫] ^y=^y?^y&_yQ_yS_yay7dymgyBhy?C BhshyuhyHiykyкkyмky1lyNly}ly┤ly?C ┤lъlyлmy╥my╧ny·nyЗoy╕oyGpy[qy?C [q]qyЙqy├qy qy+ryXry█swУtw░tu?CG ░tВuyДuyvyJwyqwyЄyy╨zyЇzy({yA{yCC A{e{yk|yП|y╣|y╩|yЬ}yd~yЯ~yб~y┼yCC ┼tАyАy╖Аy┼Аy№АyБy#Бy)БyхБyуГyCC уГхГyДwДw,Дw.ДwPДwЙДwлДwнДwGC нД╧ДyЕy(Еy*ЕyLЕy{ЕyШЕyпЕy╤ЕyЖyGG ЖЖyЖyеИwўКw Лw{ОwХПwуПwРwCG РРy┘Рy ┤У╞УyшФw2Чu4ЧuoЧsqЧsбЧs═ЧsШsGCIC Ш6ШygШyМШy░ШyуШy#Щy_ЩyНЩy═ЩyЪyIG Ъ4Ъy`ЪybЪyvЫwЫЬw┐ЬwьЬw*ЭwLЭwCG LЭ╒Эy╫Эy'ЮwрЮwЯwZЯwЧЯw╘ЯwаwGC аJаyГаyЕаy╖аw╣аwKвw7дwtдw░дwCG ░дщдyеyлеy█еyжy<зyBиyУиyсиy%йyCC %й[йy│йwєйubмsdмqЖмq╜мq╒мqнqCICIC нHнy|нyЙнyЛнy&пyЄ░y▒w╧▒u╥▒uCIC?C ╥▒є▓y┤y9╢yP╕yТ╣y╗yв╝y╪╝y5╜y~┴y?C ~┴Ж├yИ├yн├yр├yў├yz╟yP╩y┤╩yй╦y▄╦y?C ▄╦╠y╠yФ╠y╠╠y═y<═y1╬yю╬yЄ╧yв╤y?C в╤┤╤y╤╤y▐╤y╥y%╘yS╘yv╘yП╘yн╘y╦╘y?C ╦╘∙╘y╒y╒y,╒yF╒yd╒yВ╒y▓╒y╛╒y└╒y?C └╒п╓y▒╓y╩╓yф╓y╫y'╫yd╫yМ╫yЫ╫yи╫y?C и╫╛╪y-┘ye┘y╓┘w┌u#▌s6▐qO▐q|▐qCICIC |▐Я▐y▄▐y▀y▀y
▀y╒▀y нц╪чy2ъyhъyЎыy°ыyVьwБьwдьw Ўюяy яyяyяw╫яw∙яw+ЁwPЁw∙ЁwCG ∙Ё{Єy}ЄyЄyБЄyєy7єyєy~єyЮєyїyCC ї@їy╡їyўyў°y∙y.∙y[∙yБ∙yд∙y╟∙yCC ╟∙у∙y√∙y0·ye·yЪ·y╧·y╤■yЇy2yZyCC ZЙyоy░y^yЪy┘y┤ y+ └ y)yUynyУy╦y"yFw?C F yyыy╡yрyy╛w╞u$ uCIC $ ф y&ydyc
yf"yс)yу)y*y3*yo*yIC o*В*y╖*y╪*y+yU+yi+yд+y┘+y$,yIC $,&,y(,y*,yP,yv,yЫ,y▄,y-yR-yy-yIG y-а-y╟-yю-y).yb.yЙ.y░.y╫.y№.y!/yIG !/c/yг/y▄/y0y0wЙ1wx3wи3wс3wCG с3у3y╓6yc8ye8yЖ8yл8yщ8y9y+9ye9yCC e9g9yю<y#?yCy8CyXCyМCyжCy╞Cy·CyCC ·CDyRDyTDyкHyмHy▌HwIwQIwПIwGC ПI└IyёIy4JyrJyгJy╘JyKyBKyВKy┐KyGG ┐KЎKy-LydLyЫLyнLyуMw?NwiNwаNwCG аNвNy╪Py█Ty▄T ▌T CC╥═;L, C6КЛ$▒:╥═;L, C6КЛ$╨7▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄7 =жC п
'└-▓4;A╔GN∙T ZР`jgjl╪r╡x~ОГКYР8Ц╠Ь0дэйепW╡╙╗@┬╞╚r╧З╘х╪а▐#хvыЄw°■0@ * e [ < ъ X A Г ╜ ] 2 z 9 ї ═ b O ╞
!░ "% #q $╡ % & 'Б ( )P *о +0 ,н -M .└ /, 0? 19 2! 3x 4 56 6├ 7▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄=T╢▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄=БTБ]T ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
(01/01/9412/03/93T▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
w 1wq╫x яxlнy ├yg|z Иzd┼{ ▄{aF~ b~^BД BДDДydД eДwЭД ЯДu┴Д ├ДsуД фДqЕ Еo>Е @Еm`Е aЕkПЕ СЕi777777777СЕШЕ нЕy├Е ┼ЕwхЕ цЕuЖ ЖsЭЗ ║ЗnЙ ЙizЙ МЙdYЛ ПЕ СЕ7777YЛjЛv Л Мq┘М уМlшМ яМgшН ЄНbUО aО]Т ТVТ YЛ
Сy5СylСyэТy+УydУyИУy┤УyCC
рyOуyhфyнцyIC
эwGC
эDэyВэy┴эyюy?юy~юy╟юyтюyьюyЎюyGG
yZ
y└
yCC
Ё
y#
вшд5$X*┐1х7+>╘C-LЩRT k B R u v [ U
i