русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Процедуры Mark и Release


Дата добавления: 2015-06-12; просмотров: 1039; Нарушение авторских прав


Механизм действия этих процедур следующий. Пусть переменная P имеет предопределенный тип Pointer, а P1, P2, P3 и P4 объявлены как ссылочные переменные. Пусть текст программы содержит фрагмент {202}

...

New(P1);

New(P2);

Mark(P); { вызов Mark }

New(P3);

New(P4);

...

Release(P); { вызов Release }

...

Перед вызовом процедуры Release куча будет иметь вид, как на рис. 11.4.

│ │ ├──────────┤ │ ├──────────┤ │ ├──────────┤ │ ├──────────┤ │ ├──────────┤
│ │
ПУСТАЯ ЧАСТЬ КУЧИ
Данные P4^
Данные P3^
Данные P2^
Данные P1^
Записалось в P ← вызовом Mark(P)
← HeapPtr после New(P4)
← P4 (после New(P4))
← P3 (после New(P3))
← P2 (после New(P2))
← P1 (после New(P1))
∙ ∙ ∙
∙ ∙ ∙
└───────────┘
HeapOrg───→

 

Рис. 11. 4

При вызове процедуры Mark в переменную P записалось значение HeapPtr, которое было сразу после размещения P2. Далее были размещены P3 и P4, и указатель HeapPtr передвинулся туда, где он изображен на рис. 11.4.

Восстановленное из P процедурой Release(P)

Если теперь осуществить вызов Release (P), то указатель заполнения кучи HeapPtr переустановится в «позицию», которая была запомнена ранее в указателе P. Куча примет вид, показанный на рис. 11.5.



 
Записано в P ──→
вызовом Mark(P)
ПУСТАЯ ЧАСТЬ КУЧИ

 

 
Данные P2^

 

Данные P1^
 
────────────
HeapOrg ───→
←── значение HeapPtr

 

 

Рис. 11.5 {203}

Действие Release (P) проявилось в том, что куча вернулась в предыдущее состояние, «забыв» обо всех динамических переменных, созданных после выполнения процедуры Mark(P). Теперь уже не надо освобождать ссылки P3 и P4. Их нет, как будто они и не размещались.

Из механизма работы процедуры Release следует, что всю кучу можно освободить одним оператором Release ( HeapOrg ), который приводит ее к исходному пустому состоянию.

Очевидно, что пара процедур Mark/ Release — это очень мощное средство управления кучей. Они позволяют эффективно освобождать память с минимальными усилиями. Однако за это приходится платить гибкостью использования пространства кучи. При их применении освобождение памяти должно производится в порядке, обратном размещению динамических переменных. Так, например, нельзя удалить переменную P2^, не удалив при этом переменные P3^ и P4^. Для более гибкого использования кучи необходимо применять процедуры Dispose и FreeMem.

Вместе с тем не рекомендуется перемежать вызовы процедур Release с вызовами процедур Dispose и FreeMem. Две последние действуют избирательно и могут освобождать блоки памяти в используемой части кучи. Так, если после строки New(P4) в рассмотренном примере поставить вызов Dispose (P1), то перед выполнением Release (P) на месте динамической переменной P1^ будет пусто, и это пустое место могло бы быть потом использовано для размещения других данных. Координаты этого пустого (свободного) блока хранятся в специальном списке свободных блоков. Процедура Release (P) среди всего прочего стирает список свободных блоков, навсегда блокируя тем самым доступ к свободным блокам, находящимся ниже значения указателя P. Об этом надо помнить всегда, иначе можно легко и незаметно заблокировать всю кучу и потерять массу времени на нетривиальное решение вечного вопроса «почему программа не пошла?»



<== предыдущая лекция | следующая лекция ==>
Процедуры Dispose и FreeMem | Функции MaxAvail и MemAvail


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.773 сек.