Лекція 9. Доступ до пам’яті. Виділення пам’яті
1. Пам’ять
В середині наших комп`ютерів містяться чіпи RAM, тобто оперативна пам'ять, що зберігає дані для короткочасного використання. Можна зберігати файли на жорсткому диску (або SSD) для довготривалого зберігання, але коли ми його відкриємо та будемо вносити зміни, все копіюється до RAM. Попри те, що обсяг RAM значно менший та вона є тимчасовою (поки не буде вимкнене живлення), вона значно швидша.
Можна розглядати байти, які зберігаються в RAM, у вигляді сітки. Кожен байт має окрему адресу:
Насправді там розташовані мільйони або навіть мільярди байтів на кожному чіпі.
У мові програмування С коли ми створюєму змінну типу char розміром в один байт, вона буде фізично збережена в одній із таких комірок у RAM. Ціле число на чотири байти займе чотири таких комірки. Це ми можемо побачити за допомогою прикладу:
printf("s: %p\n", s);
printf("t: %p\n", t);
У цьому випадку ми кажемо printf розглядати s та t як вказівники за допомогою %p, тому ми бачимо такі адреси, як 0x2331010 і 0x2331050.
Значення надзвичайно великі (тому що у пам’яті багато комірок) і вони зазвичай записуються у шістнадцятковій системі числення. Як двійкова і десяткова системи числення, шістнадцяткова - це спосіб представлення чисел: в ній є 16 можливих значень для однієї цифри, 0-9 і A-F. (Просто так сталося, що адреси для s і tне мали абеткових символів.) Значення у шістнадцятковій системі зазвичай починається з 0x, для позначення системи числення.
Ми можемо подивитися на приклад переведення трьох байтів з десяткової системи у двійкову та у шістнядцяткову:
255 216 255
11111111 11011000 11111111
f f d 8 f f
Оскільки кожна цифра у шістнадцятковій системі має 16 можливих значень, що перетворюються на 4 двійкових цифри, кожний байт може бути виражений як дві шістнадцяткові цифри 0xff і 0xd8. Чотири 1у двійковій - це 16 у десятковій і f у шістнадцятковій системі.
2. Розподіл пам’яті
Всередині пам’яті комп’ютера різні типи даних, які повинні зберігатися для роботи нашої програми, організовані у різних областях:
Область text – скомпільований двійковий код нашої програми. Коли ми запускаємо програму, то цей код завантажується у верхній частині пам’яті.
heap – відкритий простір, в якому malloc може отримати вільну пам’ять для використання нашою програмою.
Область stack використовується функціями нашої програми, коли вони викликаються.
Глобальні змінні розташовані в областях ініціалізованих та неініціалізованих даних, а змінні середовища з командного рядка також зберігаються у відповідній області.
Функція malloc() повертає адресу на перший байт області пам'яті розміром size байт, яка була виділена з купи:
void * malloc( size_t sizemem);
Якщо пам'яті недостатньо, щоб задовольнити запит, функція malloc() повертає нульовий покажчик. Дуже важливо завжди перевіряти повертається значення на його рівність NULL, перш ніж намагатися використовувати цей покажчик. Ви намагаєтесь отримати доступ нульового покажчика зазвичай тягне крах системи.