Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Процедури і функції для роботи з динамічною пам’яттю

Проблема загублених вказівників

Робота з динамічними змінними через вказівники потребує великої ретельності i охайності при проектуванні програм. Зокрема, потрібно звільняти виділені під динамічні змінні області одразу після того, як необхідність у них відпадає, інакше “забруднення” пам’яті непотрібними динамічними змінними може привести до її швидкого вичерпання.

Крім того, необхідно враховувати ще одну проблему, пов’язану з протиріччям між стековим принципом розміщення статичних змінних i довільним характером створення i знищення динамічних змінних.

Розглянемо наступний схематичний приклад програми:

Type

PtrAnk = ^Anketa;

Anketa = Record

...

End;

Procedure GetAnketa;

var

P: PtrAnk;

Begin

P:= New (PtrAnk)

End;

Begin

WriteLn(MemAvail);

GetAnketa;

WriteLn(MemAvail)

End.

 

Виклик New в процедурі GetAnketa веде до відведення пам’яті для динамічної змінної типу Anketa. Вказівник на цю змінну присвоюється змінній P. Розглянемо ситуацію, яка створюється після виходу з процедури GetAnketa.

За правилами блочності всі локальні змінні підпрограми перестають існувати після її за вершення. В цьому випадку зникає локальна змінна P. В той же час, область пам’яті, яка відведена в процесі виконання процедури GetAnketa продовжує існувати, бо звільнити її можна тільки явно, через процедуру Dispose. Таким чином, після виходу із GetAnketa відсутній будь-який доступ до динамічної змінної, оскільки вказівник на неї відсутній.

При проектуванні програм, які інтенсивно вико­ристо­вують динамічну пам’ять необхідно уважно відноситись до даної проблеми та, або вчасно звільняти пам’ять, або, в разі необхідності, запам’ятовувати вказівник на динамічні змінні.

 


 

 

Функція ADDR(х), повертає результат типу POINTER, у якому міститься адреса аргументу.

Тут X - будь-який об'єкт програми (ім'я будь-якої змінної, процедури, функції). Повернена адреса сумісна із показником будь-якого типу. Відзначимо, що аналогічний результат повертає операція @.

 

Функція CSEG. Повертає значення, що зберігається в регістрі CS мікропроцесора (на початку роботи програми в регістрі CS міститься сегмент початку коду програми).

Результат повертається в слові типу WORD.

 

Процедура DISPOSE(ТР). Повертає в купу фрагмент динамічної пам'яті, що раніше був зарезервований за типізованим покажчиком.

Тут ТР - типізований покажчик. При повторному використанні процедури стосовно до вже звільненого фрагмента виникає помилка періоду виконання. При звільненні динамічних об'єктів можна вказувати другим параметром звертання до DISPOSE ім'я деструктора.

 

Функція DSEG. Повертає значення, що зберігається в регістрі DS мікропроцесора (на початку роботи програми в регістрі DS міститься сегмент початку даних програми).

Результат повертається в слові типу WORD.

 

Процедура FREEMEM(Р,SIZE). Повертає в купу фрагмент динамічної пам'яті, що раніше був зарезервований за нетипізованим покажчиком

Тут Р - нетипізований покажчик;

SIZE - довжина в байтах звільняємого фрагмента.

При повторному використанні процедури стосовно до вже звільненого фрагмента виникає помилка періоду виконання.

 

Процедура GETMEM(Р,SIZE). Резервує за нетипізованим покажчиком фрагмент динамічної пам'яті необхідного розміру.

За одне звертання до процедури можна зарезервувати не більш 65521 байтів динамічної пам'яті. Якщо немає вільної пам'яті необхідного розміру, виникає помилка періоду виконання. Якщо пам'ять нефрагментована, послідовні звертання до процедури будуть резервувати послідовні ділянки пам'яті, так що початок наступного буде розташовуватися відразу за кінцем попереднього.

 

Процедура MARK (PTR). Запам'ятовує поточне значення покажчика купи HEAPPTR.

Тут PTR - покажчик будь-якого типу, у якому буде повернуте поточне значення HEAPPTR. Використовується разом із процедурою RELEASE для звільнення частини купи.

 

Функція MAXAVAIL. Повертає розмір у байтах найбільшої безперервної ділянки купи.

Результат має тип LONGINT. За один виклик процедури NEW або GETMEM не можна зарезервувати пам'яті більше, чим значення, що повертається цією функцією.

 

Функція MEMAVAIL. Повертає розмір у байтах загального вільного простору купи. Результат має тип LONGINT.

 

Процедура NEW (ТР). Резервує фрагмент купи для розміщення змінної.

Тут ТР - типізований покажчик.

За одне звертання до процедури можна зарезервувати не більш 65521 байта динамічної пам'яті. Якщо немає вільної пам'яті необхідного розміру виникає помилка періоду виконання. Якщо пам'ять не фрагментована, послідовне звертання до процедури буде резервувати послідовні ділянки пам'яті, так що початок наступного буде розташовуватися відразу за кінцем попереднього.

Процедура NEW може викликатися як функція. У цьому випадку параметром звертання до неї є тип змінної, розташованої в купі, i функція NEW повертає значення типу покажчик. Наприклад:

type

Pint =^integer;

var

р: Pint;

begin

р:= New(Pint);

• • • •

end.

При розміщенні в динамічній пам'яті об'єкта дозволяється в якості другого параметра звертання до NEW вказувати ім'я конструктора.

 

Функція OFS(Х). Повертає значення типу WORD, що містить зсув адреси зазначеного об'єкта. Тут Х - вираз будь-якого типу або ім'я процедури.

 

Функція PTR(SEG, OFS). Повертає значення типу POINTER по заданому сегменті SEG і зсуву OFS.

Тут SEG - вираз типу WORD, що містить сегмент;

OFS - вираз типу WORD, що містить зсув. Значення, що повертається функцією, сумісно з покажчиком будь-якого типу.

 

Процедура RELEASE(PTR). Звільняє ділянку купи.

Тут PTR - покажчик будь-якого типу, у котрому попередньо було збережено процедурою MARK значення покажчика купи. Звільняється ділянка купи від адреси, що зберігається в PTR, до кінця купи. Одночасно знищується список усіх вільних фрагментів, що, можливо, були створені процедурами DISPOSE або FREEMEM.

 

Функція SEG(X). Повертає значення типу WORD, що містить сегмент адреси зазначеного об'єкта. Тут Х - вираз будь-якого типу або ім'я процедури.

 

Функція SIZEOF(X). Повертає довжину в байтах внутрішнього представлення зазначеного об'єкта.

Тут Х - ім'я змінної, функції або типу.

 

 


<== предыдущая лекция | следующая лекция ==>
Засоби створення та використання динамічних даних | Рекурсивні типи даних
Поделиться с друзьями:


Дата добавления: 2013-12-12; Просмотров: 697; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




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