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

Съдържание:

Anonim

Преди да научите разпределението на динамична памет 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 ()
  • Безплатната () функция
  • C calloc () Функция
  • calloc () срещу malloc (): Основни разлики
  • Функция C realloc ()
  • Динамични масиви

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

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

Сега можете да създавате и унищожавате масив от елементи динамично по време на изпълнение без никакви проблеми. В обобщение, автоматичното управление на паметта използва стека, а динамичното разпределение на паметта C използва купчината.

Библиотеката има функции, отговорни за динамичното управление на паметта.

Функция Предназначение
malloc () Разпределя паметта на заявения размер и връща показалеца към първия байт от разпределеното пространство.
calloc () Разпределя пространството за елементи от масив. Инициализира елементите до нула и връща указател към паметта.
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 () се извиква за освобождаване / освобождаване на памет в 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 на екрана:

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 () се използва за изчистване на динамично разпределената памет.