Розподіл пам'яті malloc () і са11ос ()

РОЗПОДІЛ ПАМ'ЯТІ: malloc () І са11ос ()

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

char place [] = "Залив Свинячий печінки";

і буде виділена пам'ять, достатня для запам'ятовування цього рядка.

Або ми можемо бути більш конкретні і запросити певний обсяг пам'яті:

Це опис виділяє 100 осередків пам'яті, кожна з яких призначена для запам'ятовування цілого значення.

Мова Сі не зупиняється на цьому. Він дозволяє вам розподіляти додаткову пам'ять під час роботи програми. Припустимо, наприклад, ви пишете диалоговую програму і не знаєте заздалегідь, скільки даних вам доведеться вводити. Можна виділити потрібний вам (як ви вважаєте) обсяг пам'яті, а потім, якщо знадобиться, вимагати ще. На рис. 15.5 дано приклад, в якому використовується функція malloc (). щоб зробити саме це. Крім того, зверніть увагу на те, як така програма застосовує покажчики.

/ * Додає пам'ять, якщо необхідно * /

#define STOP "" / * сигнал припинення введення * /

#define BLOCK 100 / * байти пам'яті * /

#define LIM 40 / * гранична довжина вводиться рядка * /

#define MAX 50 / * максимальне число вводяться рядків * /

char store [BLOCK]; / * Вихідний блок пам'яті * /

char symph [LIM]; / * Приймач вводяться рядків * /

char * end; / * Вказує на кінець пам'яті * /

char * starts [MAX]; / * Вказує на початку рядків * /

int index = 0; / * Кількість вводяться рядків * /

int count; / * Лічильник * /

char * malloc (); / * Розподільник пам'яті * /

end = starts [0] + BLOCK - 1;

puts ( "Назвіть кілька симфонічних оркестром.");

puts ( "Введіть по одному: натисніть клавішу [введення] на початку");

puts ( "рядки для завершення вашого списку. Добре, я готова.");

while (strcmp (fgets (symph, LIM, stdin), STOP)! = 0 index

puts ( "Зачекайте секунду. Я спробую знайти додаткову пам'ять.");

end = starts [index] + BLOCK - 1;

for (count = 0; count

strcpy (starts [index], symph);

starts [index + 1] = starts [index] + strlen (symph) + 1;

printf ( "Етo .. Продовжуйте, якщо хочете.", index);>

puts ( "Добре, ось що я отримала:");

for (count = 0; count

МАЛ. 15.5. Програма, що додає пам'ять на вимогу.

Ось зразок роботи програми:

Назвіть кілька симфонічних оркестрів оркестрів.

Вводите їх по одному; натисніть клавішу [введення] на початку

рядки для завершення нашого списку. Добре, я готова.

Це 1. Продовжуйте, якщо хочете.

Це 2. Продовжуйте, якщо хочете.

Це 3. Продовжуйте, якщо хочете.

Це 4. Продовжуйте, якщо хочете. Лондонський симфонічний

Це 5. Продовжуйте, якщо хочете. Віденський філармонічний

Зачекайте секунду. Я спробую знайти додаткову пам'ять.

Це 6. Продовжуйте, якщо хочете.

Це 7. Продовжуйте, якщо хочете.

Добре, ось що я отримала:

Спочатку давайте подивимося, що робить функція malloc (). Вона бере аргумент у вигляді цілого без знака, яке представляє кількість необхідних байтів пам'яті. Так, malloc (BLOCK) вимагає 100 байт. Функція повертає покажчик на тип char в початок нового блоку пам'яті. Ми використовували опис

щоб попередити компілятор, що malloc () повертає покажчик на тип char. Тому ми присвоїли значення цього покажчика елементу масиву starts [index] за допомогою оператора

Добре, давайте тепер розглянемо проект програми, що полягає в тому, щоб запам'ятати всі вихідні рядки підряд у великому масиві store. Ми хочемо використовувати starts [0] для посилання на початок першого рядка, starts [l] - другого рядка і т. Д. На проміжному етапі програма вводить рядок в масив symph. Ми використовували fgets () замість gets (). щоб обмежити вхідні рядок довжиною масиву symph.

МАЛ. 15.6. Послідовні рядки symph, записані в масив store.

Перш ніж копіювати symph в store. ми повинні перевірити, чи достатньо для неї місця, що залишилося. Покажчик end посилається на кінець пам'яті, а поточне значення starts [index] посилається на невикористану пам'яті. Таким чином, ми можемо порівняти різницю між цими двома покажчиками з довжиною symph і визначити, чи достатньо залишилося пам'яті.

Якщо місця недостатньо, викликаємо malloc (). щоб підготувати додаткову пам'ять. Ми встановлюємо starts [index] на початок нового блоку пам'яті, a end - на кінець нового блоку. Зауважимо, що у нас немає імені цієї нової пам'яті. Вона не є, наприклад, розширенням store. У нас є тільки позначення покажчиків, що посилаються на нову область пам'яті.

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

Але поки у нас є покажчики, ми можемо працювати з рядками, як показує нам частину програми, що виконує висновок на друк.

Таким чином використовується mаllос (). Але припустимо, що ви хочете працювати з пам'яттю типу int. а не char. Можете і тут використовувати mаllос (). Ось як це робиться:

char * malloc (); / * Як і раніше описуємо як покажчик на char * /

newmem = (int *) malloc (l00); / * Використовуємо операцію приведення типу * /

Знову потрібно 100 байт. Операція приведення типу перетворює значення, повернене покажчиком на тип char. в покажчик на тип int. Якщо, як в нашій системі, int займає два байти пам'яті, це означає, що newmem + 1 буде збільшувати покажчик на два байта, т. Е. Пересувати його до наступного цілого. Це також означає, що 100 байт можна використовувати для запам'ятовування 50 цілих чисел.

Іншу можливість розподілу пам'яті дає нам застосування функції саllос ().

newmem = (long *) calloc (100, sizeof (long));

Подібно malloc () функція саllос () повертає покажчик на char. Потрібно використовувати оператор приведення типу, якщо ви хочете запам'ятати інший тип. Ця нова функція має два аргументи, і обидва вони повинні бути цілими без знака. Перший аргумент містить кількість необхідних елементів пам'яті. Другий аргумент - розмір кожного осередку в байтах. У нашому випадку long використовує чотири байти, тому оператор виділить 100 чотирибайтових елементів, використовуючи в цілому 400 байтів пам'яті.

Застосовуючи sizeof (long) замість 4, ми зробили цю програму більш мобільною. Вона буде працювати на системах, де long має розмір, відмінний від чотирьох.

Функція саllос () має ще одну особливість; вона обнуляє вміст всього блоку.

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

Поділіться на сторінці