Динамічний розподіл пам'яті в C — це спосіб ручного керування пам'ятю в мові програмування C за допомогою функцій стандартної бібліотеки, а саме malloc, realloc, calloc, aligned_alloc та free. [1] [2]
Попри те, що ці функції наявні в C++, автори закликають використовувати більш безпечні оператори new та delete. [3] Хоча існують винятки, де їх використання не рекомендується. Серед них, чутливі до продуктивності ділянки коду або реалізація прибиральника сміття.
Існує безліч механізмів перерозподілу пам'яті, що базуються на функції malloc. Вони можуть відрізнятися за швидкістю виконання чи споживанню пам'яті.
Функції динамічного розподілу пам’яті знаходяться у заголовку stdlib.h ( заголовок cstdlib в C++).
stdlib.h
cstdlib
malloc
aligned_alloc
realloc
calloc
free
malloc()
calloc()
Створення масиву в С з десяти цілих чисел є доволі простим:
int array[10];
Але розмір масиву визначається під час компіляції. Якщо потрібно виділити його динамічно та без використання масиву змінної довжини, який присутній не в всіх реалізаціях C11, можна використати такий код:
int *array = malloc(10 * sizeof(int));
Він обчислює кількість байтів, які десять цілих чисел займають у пам’яті, потім виділяє їх через функцію malloc. Адреса виділеного блоку пам'яті зберігається у змінній array (завдяки синтаксису C, вказівники та масиви в деяких ситуаціях можуть використовуватись рівнозначно). Оскільки функція malloc не гарантує виділення пам'яті, вона може повернути нульовий вказівник у разі помилки. Перевіряти це в програмуванні вважається хорошою практикою:
array
int *array = malloc(10 * sizeof(int)); if (array == NULL) { fprintf(stderr, "malloc failed\n"); return -1; }
Після того, як динамічний масив більше не потрібен, потрібно викликати функцію free, щоб звільнити пам'ять, яку він займає:
free(array);
Пам'ять, що виділена malloc не є ініціалізована за замовчуванням та може містити залишки роботи попередніх програм. Тобто, елементи масиву виділеного за допомогою malloс є неініціалізованими змінними. Функція calloc повертає пам'ять, що очищується за замовчуванням.
malloс
int *array = calloc(10, sizeof(int));
За допомогою функції realloc ми можемо змінити розмір пам’яті, яка вже була виділеною. Наприклад, якщо у нас є вказівник, що вказує на масив розміру n {\displaystyle n} і ми хочемо змінити його розмір на m {\displaystyle m} , ми можемо скористатися realloc.
int *arr = malloc(2 * sizeof(int)); arr[0] = 1; arr[1] = 2; arr = realloc(arr, 3 * sizeof(int)); arr[2] = 3;
Варто зазначити, що realloc може повернути вказівник на нову адресу. Тобто, якщо блок пам'яті, що належить вказівнику, не може бути розширеним, realloc виділить новий блок пам'яті та зкопіює туди старі дані. Тоді попередній вказівник буде більше не дійсним.
calloc(3)