Dinamikus memóriafoglalás C-ben: malloc(), calloc()
⚡ Okos összefoglaló
A C dinamikus memóriafoglalása futásidőben lefoglalja és felszabadítja a heap memóriát az stdlib.h könyvtár malloc(), calloc(), realloc() és free() függvényeivel, lehetővé téve a programok számára, hogy rugalmasan méretezzék a tömböket és a struktúrákat, amikor a követelmények a végrehajtás előtt ismeretlenek.

Hogyan működik a memóriakezelés C-ben?
Amikor egy változót alapvető adattípussal deklarálunk, a C fordító automatikusan lefoglalja a változó számára a memóriaterületet egy veremnek nevezett memóriaterületen.
Például egy float változó deklarálása jellemzően 4 bájtot vesz igénybe (platformtól függően). Ezt az információt a sizeof operátorral ellenőrizhetjük, ahogy az az alábbi példában látható.
#include <stdio.h> int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
A kimenet a következő lesz:
The size of float is 4 bytes
Ezenkívül egy meghatározott méretű tömb összefüggő memóriablokkokban van lefoglalva, minden blokknak egy elem mérete van:
#include <stdio.h> int main() { float arr[10]; printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
Az eredmény:
The size of the float array with 10 element is 40
Ahogy eddig is tanultuk, egy alap adattípus vagy tömb deklarálásakor a memóriakezelés automatikusan történik. Létezik azonban egy memóriafoglalási folyamat C-ben, amely lehetővé teszi olyan program megvalósítását, amelyben a tömb mérete eldöntetlen a program futtatásáig (futásidejű). Ezt a folyamatot „dinamikus memóriafoglalásnak” nevezik.
Dinamikus memóriafoglalás C-ben
A dinamikus memória-elosztás a memória manuális lefoglalása és felszabadítása a programozási igényeknek megfelelően. A dinamikus memóriát olyan mutatókkal kezeljük és szolgáljuk ki, amelyek az újonnan lefoglalt memóriaterületre mutatnak egy olyan területen, amelyet halomnak nevezünk.
Mostantól probléma nélkül létrehozhat és megsemmisíthet egy elemtömböt dinamikusan futás közben. Összefoglalva, az automatikus memóriakezelés a verem, a C Dynamic Memory Allocation pedig a kupacot használja.
A A könyvtár a dinamikus memóriakezelésért felelős funkciókkal rendelkezik.
| Funkció | Cél |
|---|---|
| malloc () | Lefoglalja a kívánt méretű memóriát, és visszaadja a mutatót az első bájtjára kiosztott hely. |
| calloc() | Lefoglalja a helyet egy tömb elemei számára. Nullára inicializálja az elemeket, és visszaad egy mutatót a memóriába. |
| realloc() | A korábban lefoglalt memóriaterület méretének módosítására szolgál. |
| Ingyenes() | Felszabadítja vagy kiüríti a korábban lefoglalt memóriaterületet. |
Beszéljük meg a fenti függvényeket az alkalmazásukkal együtt
malloc() függvény C-ben
A C malloc() függvény a memóriafoglalást jelenti. Ez egy memóriablokk dinamikus lefoglalására szolgáló funkció. Meghatározott méretű memóriaterületet foglal le, és visszaadja a memóriahelyre mutató nullmutatót. A visszaadott mutató általában void típusú. Ez azt jelenti, hogy bármelyik mutatóhoz hozzárendelhetjük a C malloc() függvényt.
A malloc() függvény szintaxisa:
ptr = (cast_type *) malloc (byte_size);
Itt,
- A ptr egy cast_type mutató.
- A C malloc() függvény egy mutatót ad vissza a byte_size lefoglalt memóriájába.
Példa a malloc()-ra:
Example: ptr = (int *) malloc (50)
Ha ez az utasítás sikeresen végrehajtódik, 50 bájtos memóriaterület kerül lefoglalásra. A lefoglalt terület első bájtjának címe az int típusú ptr mutatóhoz van hozzárendelve.
Vegyünk egy másik példát:
#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)); } }
output:
Value of the 6th integer is 480
- Figyeljük meg, hogy a sizeof(*ptr) függvényt használtuk a sizeof(int) helyett, hogy a kód robusztusabb legyen, amikor a *ptr deklarációt később más adattípusra tipizáljuk.
- A kiosztás sikertelen lehet, ha a memória nem elegendő. Ebben az esetben NULL mutatót ad vissza. Tehát a NULL mutató ellenőrzéséhez kódot kell megadnia.
- Ne feledje, hogy a lefoglalt memória összefüggő, és tömbként kezelhető. A tömbelemek eléréséhez használhatunk mutató aritmetikát, nem pedig zárójeleket [ ]. Javasoljuk, hogy a + használatával hivatkozzon a tömbelemekre, mert a ++ vagy += növelés megváltoztatja a tömb által tárolt címet. mutató.
A Malloc() függvény karakteres adattípusokkal, valamint összetett adattípusokkal, például struktúrákkal is használható.
free() függvény C-ben
A memória a változók fordításkor automatikusan felszabadításra kerül. A dinamikus memóriafoglalásnál kifejezetten fel kell szabadítania a memóriát. Ha ez nem történik meg, memóriahiány léphet fel.
A free() függvény meghívásával felszabadíthatjuk/felszabadíthatjuk a memóriát a C nyelvben. A programban a memória felszabadításával több szabadíthatunk fel későbbi felhasználásra.
Például:
#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); }
output:
Value of the 2nd integer is 50
calloc() függvény C-ben
A C calloc() függvény a szomszédos allokációt jelöli. Ez a funkció több memóriablokk lefoglalására szolgál. Ez egy dinamikus memóriafoglalási funkció, amely a memória komplex adatstruktúrákhoz, például tömbökhöz és struktúrákhoz való hozzárendelésére szolgál.
A Malloc() függvény egyetlen memóriablokk lefoglalására szolgál, míg a calloc() C-ben több memóriablokk lefoglalására szolgál. A calloc() függvény által lefoglalt minden blokk azonos méretű.
A calloc() függvény szintaxisa:
ptr = (cast_type *) calloc (n, size);
A fenti utasítás n azonos méretű memóriablokk lefoglalására szolgál.
A memóriaterület lefoglalása után az összes bájt nullára inicializálódik.
Az aktuálisan lefoglalt memóriaterület első bájtjánál lévő mutató kerül visszaadásra.
Ha hiba történik a memóriaterület lefoglalásakor, például memóriahiány, nulla mutatót ad vissza.
Példa a calloc()-ra:
Az alábbi program egy számtani sorozat összegét számítja ki.
#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; }
Eredmény:
Building and calculating the sequence sum of the first 10 terms
Sum = 45
calloc() vs. malloc(): Kulcskülönbségek
Az alábbiakban bemutatjuk a legfontosabb különbséget malloc() vs calloc() C-ben:
A calloc() függvény általában alkalmasabb és hatékonyabb, mint a malloc() függvény. Míg mindkét függvény memóriaterület lefoglalására szolgál, a calloc() egyszerre több blokkot is lefoglalhat. Nem kell minden alkalommal memóriablokkot kérni. A calloc() függvényt összetett adatstruktúrákban használják, amelyek nagyobb memóriaterületet igényelnek.
A calloc() által lefoglalt memóriablokk C-ben mindig nullára van inicializálva, míg a malloc() függvényben C-ben mindig tartalmaz egy szemét értéket.
realloc() függvény C-ben
A C realloc() függvénnyel növelheted a már lefoglalt memória méretét. Kibővíti az aktuális blokkot, miközben az eredeti tartalmat változatlanul hagyja. A C-ben a realloc() a memória újrafoglalását jelenti.
A realloc() a korábban lefoglalt memória méretének csökkentésére is használható.
A realloc() függvény szintaxisa:
ptr = realloc (ptr,newsize);
A fenti utasítás egy új memóriaterületet foglal le meghatározott mérettel a newsize változóban. A funkció végrehajtása után a mutató visszakerül a memóriablokk első bájtjába. Az új méret lehet nagyobb vagy kisebb, mint az előző memória. Nem lehetünk biztosak abban, hogy az újonnan lefoglalt blokk ugyanarra a helyre fog mutatni, mint az előző memóriablokk. Ez a funkció az összes korábbi adatot átmásolja az új régióba. Biztosítja, hogy az adatok biztonságban maradjanak.
Példa a realloc()-ra:
#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; }
Amikor a realloc() C-ben sikertelen műveletet eredményez, null mutatót ad vissza, és a korábbi adatok is felszabadulnak.
Dinamikus tömbök C-ben
A C dinamikus tömbje lehetővé teszi az elemek számának igény szerinti növekedését. C A dinamikus tömböt széles körben használják a számítástechnikai algoritmusokban.
A következő programban létrehoztunk és átméreteztünk egy dinamikus tömböt C
#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] = 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 elements printf("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); }
A C Dynamic array program eredménye a képernyőn:
arr_dynamic[0]=0 arr_dynamic[1]=1 After realloc arr_dynamic[0]=0 arr_dynamic[1]=1 arr_dynamic[2]=2 arr_dynamic[3]=3

