malloc() Функция в C библиотека с ПРИМЕР
⚡ Умно обобщение
malloc() в C резервира блок памет в heap-а по време на изпълнение и връща 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() черпи от много по-големия стек.
- Данните трябва да надживеят функцията, която ги е създала, защото heap паметта се запазва, докато не бъде изрично освободена.
- Структурите и масивите трябва да се увеличават или намаляват, докато програмата се изпълнява.
Тъй като резервираният блок се връща като указател, той може да се предава между функции евтино, без да се копират основните данни.
Как да освободим памет, разпределена от malloc()
Паметта, резервирана от malloc(), се намира в heap-а и никога не се освобождава автоматично. Когато една програма продължава да разпределя памет, без да я освобождава, тя бавно изразходва цялата налична памет – дефект, известен като изтичане на памет. Функцията 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() не е върнал, включително такъв, изместен чрез аритметика на указателите.
- Съпоставете всяко разпределение със съответстващо освобождаване, преди показалецът да излезе извън обхвата.
Keeping Разпределението и освобождаването в баланс е основната дисциплина на ръчното управление на паметта в C и предотвратява както течове, така и сривове, причинени от повторно използване на освободената памет.
malloc() срещу calloc(): Ключови разлики
malloc() и calloc() И двата резервират памет в купчината, но се различават по аргументите си и по начина, по който третират новия блок. malloc() приема един аргумент - общия брой байтове, и оставя съдържанието неинициализирано, така че блокът съдържа непредсказуеми стойности, докато програмата не запише в него. calloc() приема два аргумента - броя на елементите и размера на всеки от тях, и изчиства всеки байт до нула, преди да върне показалеца.
Практическите разлики се свеждат до три точки:
- Инициализация: calloc() нулира паметта, докато malloc() не го прави, което прави malloc() малко по-бърз, когато стойностите така или иначе ще бъдат презаписани.
- Аргументи: пишете malloc(n * size), но calloc(n, size), за да резервирате същия масив.
- Случай на употреба: изберете calloc(), когато чист, нулиран блок е от значение, и malloc(), когато скоростта е предпочитана и инициализацията се обработва ръчно.
И двете функции са декларирани в stdlib.h, и двете връщат void указател или NULL при неуспех и двете връщат паметта си обратно с една и съща функция free().

