Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
R11_ДЗ_12.doc
Скачиваний:
2
Добавлен:
22.12.2018
Размер:
809.98 Кб
Скачать

Розподіл динамічної пам’яті Породження динамічних об'єктів

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

Створення (породження) динамічного об'єкта відбувається за необхідності в процесі виконання програми. При цьому в Heap-області виділяється блок ОП необхідного розміру (в залежності від типу об'єкта, на який вказує покажчик) і адреса його початку стає значенням покажчика. Керування розміщенням об'єкта в Heap-області здійснюється за допомогою стандартного покажчика HeapPtr (поточної адреси в Heap-області). Щораз при створенні динамічного об'єкта цей покажчик зміщується на число байт, яке відповідає розміру відповідної динамічної змінної.

У мовах програмування породження динамічних об'єктів здійснюється різними програмними засобами. Зокрема, у мові Pascal для цього, зазвичай, використовується стандартна процедура New. Формат звернення до цієї процедури:

New(<покажчик>).

Процедура New резервує в Heap-області місце для розміщення породжуваного динамічного об'єкту і адресу початку цього місця повертає в своєму аргументі-покажчику. При цьому породженому динамічному об'єкту не присвоюється якого-небудь значення, так що для динамічного об'єкту процедура New грає ту ж роль, що і оголошення для статичного об'єкту.

Наприклад,

var w : ^word;

begin

...

New (w);

...

end;

Доступ до динамічних об'єктів

Динамічні об'єкти, на відміну від статичних, не мають імен в звичайному розумінні цього слова. Звертання до них здійснюється опосередковано - через відповідний покажчик, і називається розіменуванням покажчика (змінною з покажчиком). У мові Pascal БНФ-нотація такого звертання має наступний вид:

<ім'я динамічної змінної> ::= <покажчик>^.

Наприклад,

w^ := 56;

writeln(‘Значення -’,w^);

Тут w^ означає динамічну змінну, на яку посилається покажчик w («*» - адреса):

w w ^

*  56

Динамічні об'єкти можуть бути складених типів. Тоді звертання до них має ускладнений вигляд. Наприклад,

A ^ [k+5] - значення k+5 елемента динамічного масиву А;

A [k+5] ^ - значення динамічної змінної, на яку вказує k+5 елемент масиву покажчиків;

Rez ^ [i].data - значення поля data i-ої компоненти динамічного масиву Rez;

Rez [i].data^ - значення динамічної змінної, на яку вказує покажчик, що є значенням поля data i-ої компоненти масива Rez.

Обробка динамічних об'єктів

Подальша робота з динамічними змінними відбувається так само, як і з статичними змінними відповідних типів. Змінні з покажчиком (а саме вони синтаксично виконують роль динамічних змінних) можна використовувати в будь-яких конструкціях мови програмування, де допускається використання статичних змінних того ж типу. Їм можна присвоювати значення, їх можна використовувати в якості операндів у виразах і параметрів підпрограм, тощо. До них можна застосовувати всі ті операції, які допустимі у відповідності із базовим типом.

Наприклад,

var i:integer;

w:^word;

begin

i:= 2;

w^:= w^*6 + i;

...

end;

Знищення динамічних об'єктів

Хоча Heap-область велика, але і її можна вичерпати, якщо не піклуватися про звільнення пам'яті, коли ті чи інші динамічні дані стають непотрібними. Окрім того, якщо динамічний об'єкт втрачає свій покажчик, то він стає "сміттям", тобто інформацією, яка займає пам'ять, але вже не потрібна (як, наприклад, динамічне число із значенням 3 на рис.1). Тому, якщо в процесі виконання програми деякий динамічний об'єкт стає непотрібним, то його можна знищити (відмовитися від виділеного для нього місця в пам'яті). Особливо істотним ефект економії пам'яті стає при видаленні великих масивів.

У мові Pascal для цього, зазвичай, використовується стандартна процедура Dispose наступного формату:

Dispose(<покажчик >),

яка звільняє блок динамічної пам'яті, на який вказує параметр-покажчик. Після цього відповідна область пам'яті стає доступною для розподілу під інші динамічні змінні; значення ж покажчика- параметра стає невизначеним.

Слід підкреслити, що процедурою Dispose знищується лише сам динамічний об'єкт, але не покажчик на нього.

З урахуванням вищезазначеного, послідовність операторів, схема виконання яких представлена на рис. 1, слід було б модифікувати таким чином:

Var p,w :^word;

begin

new(p); new(w);

p^:=3; w^:=58;

dispose(р);

p:= w;

w:= nil;

...

end;

В результаті виконання оператора p:= w динамічний об'єкт, на який раніше посилався покажчик р, стане недоступним для використання в програмі, тому цей об'єкт можна заздалегідь знищити (за допомогою процедури Dispose) і звільнити займане ним місце в пам'яті.

Схематично результати виконання окремих етапів цього фрагмента представлені на рис. 2.

Рис. 2. Використання процедури Dispose

На відміну від рис. 1, на рис. 2 динамічний об'єкт із значенням 3 зник, тобто пам’ять, що була ним зайнята, приєдналась до вільної частини пам’яті комп’ютера.

Слід зазначити, що між процедурами New і Dispose існує тісний зв'язок: кожному виклику New повинен відповідати свій виклик Dispose.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]