Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
диплом версія 1.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
361.22 Кб
Скачать

1.5 Зберігання даних

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

У Сі є три різні способи виділення пам'яті ( класи пам'яті) для об'єктів:

  • Статичний виділення пам'яті: простір для об'єктів створюється в сегменті даних програми в момент компіляції; час життя таких об'єктів збігається з часом життя цього коду. Зміна таких об'єктів веде до так званого в стандарті "невизначеному поведінки" ( англ. undefined behaviour ). На практиці ця операція приводить до помилки часу виконання.

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

  • Динамічне виділення пам'яті: блоки пам'яті потрібного розміру можуть запитуватися під час виконання програми за допомогою бібліотечних функційmalloc, realloc, calloc і free з області пам'яті, званої купою. Ці блоки звільняються і можуть бути використані знову після виклику для них функціїfree.

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

Там, де це можливо, кращим є автоматичне або статичне виділення пам'яті: такий спосіб зберігання об'єктів управляється компілятором, що звільняє програміста від труднощів ручного виділення і звільнення пам'яті, як правило, службовця джерелом важко відшукуємо помилок витоків пам'яті і повторного звільнення в програмі. На жаль, багато структур даних мають змінний розмір під час виконання програми, тому через те, що автоматично і статично виділені області повинні мати відомий фіксований розмір під час компіляції, дуже часто потрібно використовувати динамічне виділення. Масиви змінного розміру - найпоширеніший приклад такого використання пам'яті.

1.6 Набір використовуваних символів

Мова Сі був створений вже після впровадження стандарту ASCII, тому використовує майже всі його графічні символи (немає тільки $ @ `). Більш старі мови змушені були обходитися більш скромним набором - так, Фортран, Лісп і Кобол використовували тільки круглі дужки (), а в Сі є і круглі (), і квадратні [], і фігурні {}. Крім того, в Сі розрізняються великі і малі літери, а більш старі мови використовували тільки великі.

2 Динамічний розподіл пам'яті

2.1 Динамічна пам'ять та її розподіл

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

Динамічно виділена пам'яті існує, поки її явно не звільнив програміст або збиральник сміття. Це відрізняється від статичного розподілу пам'яті, яка має фіксовану тривалість. Кажуть, що об'єкт, щоб виділяються має динамічний час життя.

Завдання виконання запиту розподілу полягає в знаходженні блока невикористаної пам'яті достатнього розміру.

Проблеми при виконанні запиту розподілу:

  • Внутрішня і зовнішня фрагментації.

  • Зменшення фрагментації потребує особливої уваги, що робить реалізацію складнішою.

  • Виділення метаданих може збільшити кількість (окремих) малих виділень;

  • Формування блоків(Chunking) намагається зменшити цей ефект.

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

Динамічний розподіл пам'яті — це розподіл за запитами процесів користувача або ядра під час їхнього виконання. Розрізняють динамічне виділення тадинамічне вивільнення пам'яті. Прикладом бібліотечної та мовної підтримки засобів динамічного розподілу пам'яті є функції mallос(), free() мови С.

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

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

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