malloc() Функція в бібліотеці C із ПРИКЛАДОМ
⚡ Розумний підсумок
malloc() у C резервує блок пам'яті в купі під час виконання та повертає вказівник void на його перший байт, дозволяючи програмам запитувати пам'ять, розмір якої невідомий, доки код фактично не виконається.

Що таке malloc у C?
Функція malloc() означає розподіл пам'яті. Це функція, яка використовується для динамічного виділення блоку пам'яті. Він резервує простір пам’яті заданого розміру та повертає нульовий покажчик, що вказує на розташування пам’яті. Зазвичай повертається вказівник типу void. Це означає, що ми можемо призначити функцію malloc будь-якому покажчику.
синтаксис
ptr = (cast_type *) malloc (byte_size);
Тут,
- ptr є вказівником на cast_type.
- Функція malloc повертає вказівник на виділену пам’ять byte_size.
Example: ptr = (int *) malloc (50)
Коли цей оператор успішно виконується, резервується простір пам’яті розміром 50 байт. Адреса першого байта зарезервованого простору присвоюється покажчику ptr типу int.
Розглянемо інший приклад реалізації malloc:
#include <stdlib.h> 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
Зверніть увагу, що замість sizeof(int) було використано sizeof(*ptr), щоб зробити код більш стійким, коли оголошення *ptr пізніше буде перетворено на інший тип даних.
Розподіл може бути невдалим, якщо пам’яті недостатньо. У цьому випадку він повертає покажчик NULL. Отже, ви повинні включити код для перевірки покажчика NULL.
Майте на увазі, що виділена пам'ять є безперервною і її можна розглядати як масив. Ми можемо використовувати покажчик арифметичні операції для доступу до елементів масиву, а не використання дужок []. Ми рекомендуємо використовувати + для посилання на елементи масиву, оскільки використання інкременту ++ або += змінює адресу, що зберігається вказівником.
Функцію Malloc також можна використовувати з символьним типом даних, а також із складними типами даних, наприклад структурами.
Навіщо використовувати malloc() у C?
Статичні масиви та звичайні змінні фіксують свій розмір під час компіляції програми, що призводить до марнування місця, коли вимога виявляється меншою, і до повної невдачі, коли вона виявляється більшою. malloc() вирішує цю проблему, запитуючи пам'ять під час виконання, щоб програма могла визначити розмір буфера точно відповідно до обсягу даних, які вона отримує. Ця гнучкість під час виконання є основою... динамічний розподіл пам'яті в С.
Динамічне розподілення за допомогою malloc() є правильним вибором у кількох поширених ситуаціях:
- Обсяг введених даних невідомий, доки програма не запуститься, наприклад, не зчитає файл або список, наданий користувачем.
- Потрібні великі блоки, які переповнять обмежений стек, оскільки malloc() черпає дані з набагато більшої купи.
- Дані повинні пережити функцію, яка їх створила, оскільки купна пам'ять зберігається до її явного звільнення.
- Структури та масиви повинні збільшуватися або зменшуватися під час виконання програми.
Оскільки зарезервований блок передається назад як вказівник, його можна легко передавати між функціями без копіювання базових даних.
Як звільнити пам'ять, виділену malloc()
Пам'ять, зарезервована malloc(), знаходиться в купі та ніколи не звільняється автоматично. Коли програма продовжує виділяти пам'ять без звільнення, вона повільно споживає всю доступну пам'ять, цей дефект відомий як витік пам'яті. Функція free() повертає системі завершений блок, щоб простір можна було використовувати повторно.
Функція free() приймає один аргумент, вказівник, який повернула функція malloc(), і звільняє весь блок одразу:
int *ptr; ptr = malloc(10 * sizeof(int)); if (ptr != NULL) { /* use the allocated memory here */ free(ptr); /* release the block */ ptr = NULL; /* avoid a dangling pointer */ }
Дотримуйтесь цих правил для безпечного керування динамічною пам'яттю:
- Викликайте free() рівно один раз для кожного успішного malloc(); звільнення одного й того ж блоку двічі призводить до невизначеної поведінки.
- Встановіть вказівник на NULL після звільнення, щоб його не можна було повторно використовувати як висячий вказівник.
- Ніколи не звільняє() вказівник, який malloc() не повернув, включаючи той, що зміщений за допомогою арифметики вказівників.
- Зіставте кожне виділення з відповідним випуском, перш ніж вказівник вийде за межі області видимості.
Кіping Розподіл та звільнення пам'яті в балансі є основною дисципліною ручного управління пам'яттю в C, і вона запобігає як витокам, так і збоям, спричиненим повторним використанням звільненої пам'яті.
malloc() проти calloc(): ключові відмінності
malloc() та calloc() Обидва резервують пам'ять купи, але вони відрізняються своїми аргументами та тим, як вони обробляють новий блок. malloc() приймає один аргумент, загальну кількість байтів, і залишає вміст неініціалізованим, тому блок зберігає непередбачувані значення сміття, доки програма не запише в нього. calloc() приймає два аргументи, кількість елементів та розмір кожного, і очищує кожен байт до нуля перед поверненням вказівника.
Практичні відмінності зводяться до трьох моментів:
- Ініціалізація: calloc() обнуляє пам'ять, тоді як malloc() цього не робить, що робить malloc() трохи швидшим, коли значення все одно будуть перезаписані.
- Аргументи: ви пишете malloc(n * size), але calloc(n, size) для резервування того самого масиву.
- Випадок використання: оберіть calloc(), коли важливий чистий, обнулений блок, та malloc(), коли перевага надається швидкості, а ініціалізація виконується вручну.
Обидві функції оголошені в stdlib.h, обидві повертають покажчик void або NULL у разі невдачі, і обидві передають свою пам'ять назад за допомогою однієї й тієї ж функції free().

