Dynamische geheugentoewijzing in C: malloc(), calloc() functies
Voordat je C Dynamische Geheugentoewijzing leert, laten we het eerst eens begrijpen:
Hoe werkt geheugenbeheer in C?
Wanneer u een variabele declareert met een basaal gegevenstype, wijst de C-compiler automatisch geheugenruimte voor de variabele toe in een geheugenpool die de stack wordt genoemd.
Een float-variabele neemt bijvoorbeeld 4 bytes in beslag (afhankelijk van het platform) wanneer deze wordt gedeclareerd. We kunnen deze informatie controleren met behulp van de sizeof operator, zoals in onderstaand voorbeeld
#include <stdio.h>int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
De uitvoer zal zijn:
The size of float is 4 bytes
Ook wordt een array met een opgegeven grootte gealloceerd in aaneengesloten blokken geheugen, waarbij elk blok de grootte voor één element heeft:
#include <stdio.h>int main() { float arr;printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
Het resultaat is:
The size of the float array with 10 element is 40
Zoals tot nu toe geleerd, wordt bij het declareren van een basis-datatype of een array het geheugen automatisch beheerd. Er is echter een proces voor het toewijzen van geheugen in C dat u in staat stelt een programma te implementeren waarin de grootte van de array onbeslist blijft totdat u uw programma uitvoert (runtime). Dit proces heet “Dynamische geheugen toewijzing”.
In deze tutorial leert u-
- Hoe geheugenbeheer in C werkt?
- Dynamische geheugentoewijzing in C
- De malloc() functie
- De free() functie
- De calloc() functie
- calloc() vs. malloc(): Belangrijkste Verschillen
- C realloc() Functie
- Dynamische Arrays
Dynamische Geheugentoewijzing in C
Dynamische Geheugentoewijzing is het handmatig toewijzen en vrijmaken van geheugen naar gelang uw programmeerbehoefte. Dynamisch geheugen wordt beheerd en bediend met pointers die wijzen naar de nieuw toegewezen geheugenruimte in een gebied dat we de heap noemen.
Nu kunt u zonder problemen een array van elementen dynamisch maken en vernietigen tijdens runtime. Samenvattend: het automatische geheugenbeheer gebruikt de stack, en de C Dynamic Memory Allocation gebruikt de heap.
De <stdlib.h> bibliotheek heeft functies die verantwoordelijk zijn voor Dynamisch Geheugen Beheer.
Functie | Doel |
Plaatst het geheugen van de gevraagde grootte toe en geeft de pointer naar de eerste byte van de toegewezen ruimte terug. | |
calloc() | Plaatst de ruimte voor elementen van een array toe. Initialiseert de elementen op nul en geeft een pointer naar het geheugen terug. |
realloc() | Het wordt gebruikt om de grootte van eerder toegewezen geheugenruimte te wijzigen. |
Vrijt of maakt de eerder toegewezen geheugenruimte leeg. |
Laten we de bovenstaande functies met hun toepassing bespreken
C malloc() Functie
De C malloc() functie staat voor geheugen toewijzing. Het is een functie die wordt gebruikt om dynamisch een blok geheugen toe te wijzen. Het reserveert geheugenruimte van gespecificeerde grootte en retourneert de null pointer die wijst naar de geheugenlocatie. De teruggegeven pointer is meestal van het type void. Dit betekent dat we C malloc() functie kunnen toewijzen aan elke pointer.
Syntaxis van malloc() functie:
ptr = (cast_type *) malloc (byte_size);
Hier,
- ptr is een pointer van cast_type.
- De C malloc() functie retourneert een pointer naar het toegewezen geheugen van byte_size.
Voorbeeld van malloc():
Example: ptr = (int *) malloc (50)
Wanneer dit statement succesvol wordt uitgevoerd, wordt een geheugenruimte van 50 bytes gereserveerd. Het adres van de eerste byte van de gereserveerde ruimte wordt toegewezen aan de pointer ptr van het type int.
Overweeg een ander voorbeeld:
#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)); }}
Uitvoer:
Value of the 6th integer is 480
- Merk op dat sizeof(*ptr) is gebruikt in plaats van sizeof(int) om de code robuuster te maken wanneer de *ptr declaratie later wordt getypecast naar een ander datatype.
- De toewijzing kan mislukken als er niet genoeg geheugen is. In dat geval wordt een NULL pointer geretourneerd. Je moet dus code inbouwen om te controleren op een NULL pointer.
- Bedenk dat het toegewezen geheugen aaneengesloten is en dat het als een array kan worden behandeld. We kunnen pointeraritmetiek gebruiken om de array-elementen te benaderen in plaats van haakjes te gebruiken. We adviseren om + te gebruiken om te verwijzen naar array-elementen, omdat het gebruik van incrementatie ++ of += het adres verandert dat is opgeslagen door de pointer.
Malloc() functie kan ook worden gebruikt met het karakter datatype, alsmede complexe datatypen zoals structuren.
De free() functie
Het geheugen voor variabelen wordt automatisch gedetalloceerd tijdens het compileren. Bij dynamische geheugentoewijzing moet je geheugen expliciet dealloceren. Als je dat niet doet, kun je een “out of memory” fout krijgen.
De functie free() wordt in C aangeroepen om geheugen vrij te maken/dealloceren. Door geheugen vrij te maken in uw programma, maakt u meer beschikbaar voor later gebruik.
Voorbeeld:
#include <stdio.h>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);}
Uitvoer
Value of the 2nd integer is 50
C calloc() Functie
De C calloc() functie staat voor contiguous allocation. Deze functie wordt gebruikt om meerdere blokken geheugen toe te wijzen. Het is een dynamische geheugentoewijzingsfunctie die wordt gebruikt om het geheugen toe te wijzen aan complexe gegevensstructuren, zoals arrays en structuren.
Malloc() functie wordt gebruikt om een enkel blok geheugenruimte toe te wijzen, terwijl de calloc() in C wordt gebruikt om meerdere blokken geheugenruimte toe te wijzen. Elk blok dat door de calloc() functie wordt toegewezen, heeft dezelfde grootte.
Syntax van calloc() functie:
ptr = (cast_type *) calloc (n, size);
- Het bovenstaande statement wordt gebruikt om n geheugenblokken van dezelfde grootte toe te wijzen.
- Nadat de geheugenruimte is toegewezen, worden alle bytes op nul geïnitialiseerd.
- De pointer die zich op dat moment op de eerste byte van de toegewezen geheugenruimte bevindt, wordt teruggegeven.
Wanneer er een fout optreedt bij het toewijzen van geheugenruimte, zoals een tekort aan geheugen, dan wordt een null pointer geretourneerd.
Voorbeeld van calloc():
Het onderstaande programma berekent de som van een rekenkundige reeks.
#include <stdio.h> 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; }
Resultaat:
Building and calculating the sequence sum of the first 10 termsSum = 45
calloc() vs. malloc(): Belangrijkste Verschillen
Hieronder staan de belangrijkste verschillen tussen malloc() vs calloc() in C:
De calloc() functie is over het algemeen geschikter en efficiënter dan die van de malloc() functie. Hoewel beide functies worden gebruikt om geheugenruimte toe te wijzen, kan calloc() meerdere blokken in een keer toewijzen. Je hoeft dus niet elke keer om een geheugenblok te vragen. De calloc() functie wordt gebruikt in complexe datastructuren die meer geheugenruimte nodig hebben.
Het geheugenblok dat door een calloc() in C wordt gealloceerd, wordt altijd op nul ge¨ınitialiseerd, terwijl het in de functie malloc() in C altijd een garbage-waarde bevat.
C realloc() Functie
Met behulp van de C realloc() functie kunt u meer geheugen toevoegen aan reeds toegewezen geheugen. Het breidt het huidige blok uit terwijl de oorspronkelijke inhoud blijft zoals die is. realloc() in C staat voor het opnieuw toewijzen van geheugen.
realloc() kan ook worden gebruikt om de grootte van het eerder toegewezen geheugen te verkleinen.
Syntaxis van realloc() Functie:
ptr = realloc (ptr,newsize);
Het bovenstaande statement wijst een nieuwe geheugenruimte toe met een opgegeven grootte in de variabele newsize. Na het uitvoeren van de functie wordt de pointer teruggegeven aan de eerste byte van het geheugenblok. De nieuwe grootte kan groter of kleiner zijn dan het vorige geheugen. We kunnen er niet zeker van zijn dat het nieuw toegewezen blok naar dezelfde plaats zal wijzen als die van het vorige geheugenblok. Deze functie kopieert alle vorige gegevens naar het nieuwe gebied. Het zorgt ervoor dat de gegevens veilig blijven.
Voorbeeld van realloc():
#include <stdio.h>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 size strcat(ptr, " In 'C'"); printf(" %s, Address = %u\n", ptr, ptr); free(ptr); return 0;}
Wanneer de realloc() in C resulteert in een mislukte operatie, retourneert het een null pointer, en de vorige gegevens worden ook vrijgemaakt.
Dynamische arrays in C
Een dynamische array in C staat toe dat het aantal elementen groeit als dat nodig is. Dynamische matrices in C worden veel gebruikt in algoritmen voor computer science.
In het volgende programma hebben we een Dynamische matrix in C gemaakt en van grootte veranderd
#include <stdio.h> int main() { int * arr_dynamic = NULL; int elements = 2, i; arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks for (i = 0; i < elements; i++) arr_dynamic = i; for (i = 0; i < elements; i++) printf("arr_dynamic=%d\n", i, arr_dynamic); elements = 4; arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements printf("After realloc\n"); for (i = 2; i < elements; i++) arr_dynamic = i; for (i = 0; i < elements; i++) printf("arr_dynamic=%d\n", i, arr_dynamic); free(arr_dynamic); }
Resultaat van C Dynamische matrix programma op het scherm:
arr_dynamic=0arr_dynamic=1After reallocarr_dynamic=0arr_dynamic=1arr_dynamic=2arr_dynamic=3
Samenvatting
- We kunnen het geheugen dynamisch beheren door naar behoefte geheugenblokken in de heap aan te maken
- In C Dynamic Memory Allocation wordt geheugen tijdens een run-time toegewezen.
- Dynamische geheugentoewijzing maakt het mogelijk strings en arrays te manipuleren waarvan de grootte flexibel is en op elk moment in uw programma kan worden gewijzigd.
- Het is nodig wanneer u geen idee hebt hoeveel geheugen een bepaalde structuur in beslag zal nemen.
- Malloc() in C is een dynamische geheugentoewijzingsfunctie die staat voor geheugentoewijzing die blokken geheugen met de specifieke grootte initialiseert op een vuilniswaarde
- Calloc() in C is een contiguous geheugentoewijzingsfunctie die meerdere geheugenblokken tegelijk toewijst die geïnitialiseerd zijn op 0
- Realloc() in C wordt gebruikt om geheugen opnieuw toe te wijzen op basis van de opgegeven grootte.
- Free() functie wordt gebruikt om het dynamisch toegewezen geheugen te wissen.