Динамічне розподіл пам'яті на мові C: функції malloc (), calloc ()

Перш ніж вивчити розподіл динамічної пам'яті C, давайте зрозуміємо:

Як працює управління пам'яттю в C?

Коли ви оголошуєте змінну за допомогою базового типу даних, компілятор C автоматично виділяє простір пам'яті для змінної у пулі пам'яті, який називається стеком .

Наприклад, плаваюча змінна зазвичай приймає 4 байти (відповідно до платформи), коли вона оголошена. Ми можемо перевірити цю інформацію за допомогою оператора sizeof, як показано в прикладі нижче

#include int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

Результатом буде:

 The size of float is 4 bytes 

Крім того, масив із заданим розміром виділяється в суміжні блоки пам'яті, кожен блок має розмір для одного елемента:

#include int main() { float arr[10];printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;} 

Результат:

 The size of the float array with 10 element is 40

Як ми дізналися на сьогоднішній день, при оголошенні базового типу даних або масиву пам’ять автоматично управляється. Однак існує процес розподілу пам'яті в C, який дозволить вам реалізувати програму, в якій розмір масиву не визначений, поки ви не запустите програму (час виконання). Цей процес називається " Динамічне розподіл пам'яті ".

У цьому підручнику ви дізнаєтесь-

  • Як працює управління пам'яттю в C?
  • Динамічне розподіл пам'яті в C
  • Функція C malloc ()
  • Функція free ()
  • C calloc () Функція
  • calloc () проти malloc (): Основні відмінності
  • Функція C realloc ()
  • Динамічні масиви

Динамічне розподіл пам'яті в C

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

Тепер ви можете без проблем динамічно створювати та знищувати масив елементів під час виконання. Підводячи підсумок, автоматичне керування пам'яттю використовує стек, а динамічне розподіл пам'яті C використовує купу.

Бібліотека має функції, що відповідають за динамічне управління пам'яттю.

Функція Призначення
malloc () Виділяє пам'ять запитуваного розміру і повертає покажчик на перший байт виділеного простору.
мозоль () Виділяє місце для елементів масиву. Ініціалізує елементи до нуля і повертає вказівник на пам’ять.
realloc () Він використовується для зміни розміру раніше виділеного місця в пам'яті.
Безкоштовно () Звільняє або звільняє раніше виділений простір пам'яті.

Обговоримо вищезазначені функції з їх застосуванням

Функція C malloc ()

Функція C malloc () означає виділення пам'яті. Це функція, яка використовується для динамічного розподілу блоку пам'яті. Він зберігає простір у пам'яті заданого розміру і повертає нульовий покажчик, що вказує на місце в пам'яті. Показник, що повертається, зазвичай має тип void. Це означає, що ми можемо призначити функцію C malloc () будь-якому покажчику.

Синтаксис функції malloc ():

ptr = (cast_type *) malloc (byte_size);

Ось,

  • ptr - це покажчик cast_type.
  • Функція C malloc () повертає покажчик на виділену пам'ять byte_size.

Приклад malloc ():

Example: ptr = (int *) malloc (50)

Коли цей оператор успішно виконується, резервується простір пам'яті 50 байт. Адреса першого байта зарезервованого простору призначається покажчику ptr типу int.

Розглянемо ще один приклад:

#include int main(){int *ptr;ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */if (ptr != NULL) {*(ptr + 5) = 480; /* assign 480 to sixth integer */printf("Value of the 6th integer is %d",*(ptr + 5));}}

Вихід:

Value of the 6th integer is 480

  1. Зверніть увагу, що sizeof (* ptr) використовувався замість sizeof (int) , щоб зробити код надійнішим, коли пізніше декларація * ptr буде введена до іншого типу даних.
  2. Розподіл може не вдатися, якщо пам’яті недостатньо. У цьому випадку він повертає покажчик NULL. Отже, слід включити код для перевірки на покажчик NULL.
  3. Майте на увазі, що виділена пам’ять є суміжною і її можна розглядати як масив. Ми можемо використовувати арифметику покажчика для доступу до елементів масиву, а не за допомогою дужок []. Ми радимо використовувати + для посилання на елементи масиву, оскільки використання приросту ++ або + = змінює адресу, що зберігається покажчиком.

Функцію Malloc () можна також використовувати з типом даних символів, а також із складними типами даних, такими як структури.

Функція free ()

Пам'ять для змінних автоматично вивільняється під час компіляції. При динамічному розподілі пам'яті вам доведеться явно звільнити пам'ять. Якщо цього не зробити, ви можете зіткнутися з помилкою, що втратила пам’ять.

Функція free () викликається для звільнення / вивільнення пам'яті в C. Звільняючи пам'ять у вашій програмі, ви робите більше доступним для подальшого використання.

Наприклад:

#include int main() {int* ptr = malloc(10 * sizeof(*ptr));if (ptr != NULL){*(ptr + 2) = 50;printf("Value of the 2nd integer is %d",*(ptr + 2));}free(ptr);}

Вихідні дані

 Value of the 2nd integer is 50

C calloc () Функція

Функція C calloc () означає суміжне виділення. Ця функція використовується для виділення декількох блоків пам'яті. Це функція динамічного розподілу пам'яті, яка використовується для розподілу пам'яті для складних структур даних, таких як масиви та структури.

Функція Malloc () використовується для виділення одного блоку пам'яті, тоді як calloc () у C - для виділення декількох блоків пам'яті. Кожен блок, виділений функцією calloc (), однакового розміру.

Синтаксис функції calloc ():

ptr = (cast_type *) calloc (n, size);
  • Наведене вище твердження використовується для виділення n блоків пам'яті однакового розміру.
  • Після виділення місця в пам'яті всі байти ініціалізуються до нуля.
  • Повертається покажчик, який на даний момент знаходиться в першому байті виділеного простору пам'яті.

Щоразу, коли виникає помилка при розподілі місця в пам'яті, наприклад, дефіцит пам'яті, повертається нульовий покажчик.

Приклад calloc ():

Програма нижче обчислює суму арифметичної послідовності.

#include int main() {int i, * ptr, sum = 0;ptr = calloc(10, sizeof(int));if (ptr == NULL) {printf("Error! memory not allocated.");exit(0);}printf("Building and calculating the sequence sum of the first 10 terms \ n ");for (i = 0; i < 10; ++i) { * (ptr + i) = i;sum += * (ptr + i);}printf("Sum = %d", sum);free(ptr);return 0;}

Результат:

Building and calculating the sequence sum of the first 10 termsSum = 45

calloc () проти malloc (): Основні відмінності

Нижче наведено ключову різницю між malloc () Vs calloc () у C:

Функція calloc (), як правило, є більш придатною та ефективною, ніж функція malloc (). Хоча обидві функції використовуються для розподілу місця в пам'яті, calloc () може виділяти кілька блоків одночасно. Вам не потрібно кожного разу запитувати блок пам'яті. Функція calloc () використовується у складних структурах даних, які потребують більше місця в пам'яті.

Блок пам'яті, виділений calloc () в C, завжди ініціалізується до нуля, тоді як у функції malloc () в C, він завжди містить значення сміття.

Функція C realloc ()

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

realloc () також можна використовувати для зменшення розміру раніше виділеної пам'яті.

Синтаксис функції realloc ():

ptr = realloc (ptr,newsize);

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

Приклад realloc ():

#include int main () {char *ptr;ptr = (char *) malloc(10);strcpy(ptr, "Programming");printf(" %s, Address = %u\n", ptr, ptr);ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new sizestrcat(ptr, " In 'C'");printf(" %s, Address = %u\n", ptr, ptr);free(ptr);return 0;} 

Всякий раз, коли realloc () в C призводить до невдалої операції, він повертає нульовий покажчик, і попередні дані також звільняються.

Динамічні масиви в C

Динамічний масив в C дозволяє збільшувати кількість елементів за необхідності. C Динамічні масиви широко використовуються в алгоритмах інформатики.

У наступній програмі ми створили та змінили розмір динамічного масиву в C

#include int main() {int * arr_dynamic = NULL;int elements = 2, i;arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocksfor (i = 0; i < elements; i++) arr_dynamic[i] = i;for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);elements = 4;arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elementsprintf("After realloc\n");for (i = 2; i < elements; i++) arr_dynamic[i] = i;for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]);free(arr_dynamic);} 

Результат програми C Dynamic array на екрані:

arr_dynamic[0]=0arr_dynamic[1]=1After reallocarr_dynamic[0]=0arr_dynamic[1]=1arr_dynamic[2]=2arr_dynamic[3]=3

Резюме

  • Ми можемо динамічно керувати пам'яттю, створюючи блоки пам’яті, як це потрібно в купі
  • У динамічному розподілі пам'яті C пам'ять виділяється під час виконання.
  • Динамічне розподіл пам’яті дозволяє маніпулювати рядками та масивами, розмір яких є гнучким та може бути змінений будь-коли у вашій програмі.
  • Це потрібно, коли ви не уявляєте, скільки пам'яті займе певна структура.
  • Malloc () на мові C - це функція динамічного розподілу пам’яті, що означає виділення пам’яті, яка блокує пам’ять певного розміру, ініціалізовану до значення сміття
  • Calloc () у C - це суцільна функція розподілу пам'яті, яка виділяє кілька блоків пам'яті за один раз, ініціалізований до 0
  • Realloc () в C використовується для перерозподілу пам'яті відповідно до заданого розміру.
  • Функція Free () використовується для очищення динамічно виділеної пам'яті.

Цікаві статті...