- •Лабораторна робота № 5 Визначень об'єму пам'яті для структур
- •Короткі теоретичні відомості Принципи розподілу пам'яті
- •Види змінних і областей пам'яті. Розподіл пам'яті для змінних скалярних типів
- •Розподіл пам'яті для складних структур даних .
- •Вирівнювання меж областей пам'яті
- •Види областей пам'яті. Статичне і динамічне скріплення . Глобальна і локальна пам'ять .
- •Статична і динамічна пам'ять .
- •Вимоги до оформлення звіту
- •Основні контрольні питання
- •Варіанти початкових граматик
- •Варіанти завдань
- •Література, що рекомендується
Види змінних і областей пам'яті. Розподіл пам'яті для змінних скалярних типів
У всіх мовах програмування існує поняття так званих «базових типів даних», які також називають основними або скалярними типами. Розмір області пам'яті, необхідний для лексичної одиниці скалярного типу, вважається заздалегідь відомим. Він визначається семантикою мови і архітектурою цільової обчислювальної системи
Наприклад, в мові програмування C базовими типами даних є типи char,int, long int і т. п. (реально цих типів, звичайно, більше, ніж три), а в мові програмування Pascal — типи byte, char, word, integer і т. п.. Розмір базового типу int в мові C для архітектури комп'ютера на базі 16-розрядних процесорів складає 2 байти, а для 32-розрядних процесорів — 4 байти. Розробники початкової програми на цій мові, звичайно, можуть дізнатися дану інформацію, але якщо її використовувати в початковій програмі безпосередньо, то така програма буде жорстко прив'язана до конкретної архітектури цільової обчислювальної системи. Щоб виключити цю залежність, краще використовувати механізм визначення розміру пам'яті для типу даних, що надається мовою програмування — в мові C це функція sizeof.
Розподіл пам'яті для складних структур даних .
Для складніших структур даних використовуються правила розподілу пам'яті, визначені семантикою (сенсом) цих структур. Ці правила достатньо прості і, в принципі, однакові у всіх мовах програмування..
Ось правила розподілу пам'яті під основні види структур даних:
для масивів — числа елементів в масиві на розмір пам'яті для одного елементу (то ж правило застосовно і для рядків, але в багатьох мовах рядка містять ще і додаткову службову інформацію фіксованого об'єму);
для структур (записів з іменованими полями) — сума розмірів пам'яті по всіх полях структури;
для об'єднань ( загальних областей, записів з варіантами) — розмір максимального поля в об'єднанні;
для реалізації об'єктів (класів) — розмір пам'яті для структури з такими ж іменованими полями плюс пам'ять під службову інформацію об'єктно-орієнтованої мови (як правило, фіксованого об'єму).
Формули для обчислення об'єму пам'яті можна записати таким чином:
для масивів: Vмас = i=1,n(mi)* Vэл:
де n — розмірність масиву, mi — кількість елементів i-ої розмірності, Vэл — об'єм пам'яті для одного елементу;
для структур: Vстр = i=1,nVполяiдля структур:
де n — загальна кількість полів в структурі, Vполяi — об'єм пам'яті для i-го поля структури;
для об'єднань: Vстр = maxi=1,nVполяi :
де n — загальна кількість полів в об'єднанні, Vполяi — об'єм пам'яті для i-го поля об'єднання.
Для складніших структур даних вхідної мови об'єм пам'яті, що відводиться під ці структури даних, обчислюється рекурсивно. Наприклад, якщо є масив структур, то при обчисленні об'єму пам'яті, що відводиться під цей масив, для обчислення об'єму пам'яті, необхідної для одного елементу масиву, буде викликана процедура обчислення пам'яті структури. Такий підхід визначення об'єму займаної пам'яті дуже зручний, якщо декларативна частина мови представлена у вигляді дерева типів. Тоді для обчислення об'єму пам'яті, займаної типом з кожної вершини дерева, потрібно обчислити об'єм пам'яті для всіх «нащадків» цієї вершини, а потім застосувати формулу, пов'язану безпосередньо з самою вершиною (цей механізм подібний до механізму СУ-перекладу, вживаного при генерації коду). Якраз такого типу деревоподібні конструкції будує синтаксичний аналіз для декларативної частини мови.
Наприклад, якщо розглянути фрагмент тексту вхідної програми на мові Pascal:
...
type
arr1 = array[1..10,1..20] of integer;
rec1 = record
v1: word;
a1: arr1;
end;
rec2 = record
v1: byte;
case (v2: integer) of
0: v3: byte;
1: v4: word;
3: v5: integer;
end;
arr2 = array[1..100] of rec2;
var
aa1: arr1;
vv1,vv2,vv3,vv4: byte;
rr1: rec1;
aa2arr2;
...
Тоді, якщо відомо, що розмір скалярних типів даних byte, word і integer складає для цільової обчислювальної системи 1, 2 і 4 байти відповідно, то можна порахувати, що розмір типу arr1 складатиме V1 = 10*20*4 = 800 байт, розмір типу rec1 складе V2 = 2+800 = 802 байти, розмір типу rec2 складе V3 = 1+4+Max(1,2,4) = 9 байт, а розмір типу arr2 складе V4 = 100*9 = 900 байт. Тоді для розміщення змінної aa1 буде потрібно 800 байт пам'яті, для розміщення змінних vv1,vv2,vv3,vv4 буде потрібно 4 байти пам'яті, для змінній rr1 – 802 байти, а для змінній aa2 – ще 900 байт. Таким чином, для розміщення в пам'яті всієї описаної структури даних потрібно буде виділити V = 2506 байт пам'яті.