Dinamička alokacija memorije u C-u: malloc(), calloc()
⚡ Pametni sažetak
Dinamička alokacija memorije u C-u rezervira i oslobađa heap memoriju tijekom izvođenja pomoću funkcija malloc(), calloc(), realloc() i free() iz biblioteke stdlib.h, omogućujući programima fleksibilno dimenzioniranje nizova i struktura kada su zahtjevi nepoznati prije izvršavanja.
Kako funkcionira upravljanje memorijom u C-u?
Kada deklarirate varijablu koristeći osnovni tip podataka, C kompajler automatski dodjeljuje memorijski prostor za varijablu u memorijskom skupu koji se naziva stog.
Na primjer, varijabla s float brojem obično zauzima 4 bajta (ovisno o platformi) kada se deklarira. Ove informacije možemo provjeriti pomoću operatora sizeof kao što je prikazano u donjem primjeru.
#include <stdio.h> int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
Izlaz će biti:
The size of float is 4 bytes
Također, polje s određenom veličinom alocirano je u susjednim blokovima memorije, svaki blok ima veličinu za jedan element:
#include <stdio.h> int main() { float arr[10]; printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
Rezultat je:
The size of the float array with 10 element is 40
Kao što je do sada naučeno, prilikom deklariranja osnovnog tipa podataka ili niza, memorija se automatski upravlja. Međutim, postoji proces za alokaciju memorije u C-u koji će vam omogućiti implementaciju programa u kojem je veličina niza neodređena dok ne pokrenete program (runtime). Taj se proces naziva "Dinamička alokacija memorije".
Dinamička dodjela memorije u C
Dinamička alokacija memorije je ručna alokacija i oslobađanje memorije prema vašim programskim potrebama. Dinamičkom memorijom se upravlja i poslužuje pokazivači koji pokazuju na novododijeljeni memorijski prostor u području koje nazivamo hrpom (heap).
Sada možete stvarati i uništavati niz elemenata dinamički tijekom izvođenja bez ikakvih problema. Ukratko, automatsko upravljanje memorijom koristi stog, a C dinamička dodjela memorije koristi hrpu.
The biblioteka ima funkcije odgovorne za dinamičko upravljanje memorijom.
| funkcija | Svrha |
|---|---|
| malloc () | Dodjeljuje memoriju tražene veličine i vraća pokazivač na prvi bajt od dodijeljeni prostor. |
| calloc() | Dodjeljuje prostor za elemente niza. Inicijalizira elemente na nulu i vraća pokazivač u memoriju. |
| realloc() | Koristi se za promjenu veličine prethodno dodijeljenog memorijskog prostora. |
| Besplatno() | Oslobađa ili prazni prethodno dodijeljeni memorijski prostor. |
Razmotrimo gore navedene funkcije s njihovom primjenom
funkcija malloc() u C-u
Funkcija C malloc() označava dodjelu memorije. To je funkcija koja se koristi za dinamičku dodjelu bloka memorije. Rezervira memorijski prostor određene veličine i vraća nulti pokazivač koji pokazuje na memorijsku lokaciju. Vraćeni pokazivač obično je tipa void. To znači da C malloc() funkciju možemo dodijeliti bilo kojem pokazivaču.
Sintaksa funkcije malloc():
ptr = (cast_type *) malloc (byte_size);
Ovdje,
- ptr je pokazivač na cast_type.
- Funkcija C malloc() vraća pokazivač na dodijeljenu memoriju byte_size.
Primjer malloc():
Example: ptr = (int *) malloc (50)
Kada se ova izjava uspješno izvrši, rezervira se memorijski prostor od 50 bajtova. Adresa prvog bajta rezerviranog prostora dodjeljuje se pokazivaču ptr tipa int.
Razmotrite još jedan primjer:
#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)); } }
Izlaz:
Value of the 6th integer is 480
- Primijetite da je korištena sizeof(*ptr) umjesto sizeof(int) kako bi kod bio robusniji kada se deklaracija *ptr kasnije pretvori u drugi tip podataka.
- Dodjeljivanje možda neće uspjeti ako memorija nije dovoljna. U ovom slučaju, vraća NULL pokazivač. Dakle, trebali biste uključiti kod za provjeru pokazivača NULL.
- Imajte na umu da je dodijeljena memorija kontinuirana i da se može tretirati kao niz. Možemo koristiti aritmetiku pokazivača za pristup elementima niza umjesto korištenja zagrada []. Savjetujemo da koristite + za pozivanje na elemente polja jer korištenje inkrementacije ++ ili += mijenja adresu pohranjenu od strane pokazivač.
Funkcija Malloc() također se može koristiti sa karakternim tipom podataka, kao i sa složenim tipovima podataka kao što su strukture.
funkcija free() u C-u
Uspomena za varijable automatski se poništava tijekom kompilacije. U dinamičkoj dodjeli memorije morate eksplicitno osloboditi memoriju. Ako to ne učinite, mogli biste naići na pogrešku nedostatka memorije.
Funkcija free() poziva se za oslobađanje/dealociranje memorije u C-u. Oslobađanjem memorije u vašem programu, činite više memorije dostupnom za kasniju upotrebu.
Na primjer:
#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); }
Izlaz:
Value of the 2nd integer is 50
funkcija calloc() u C-u
Funkcija C calloc() označava kontinuiranu dodjelu. Ova se funkcija koristi za dodjelu više blokova memorije. To je funkcija dinamičke dodjele memorije koja se koristi za dodjelu memorije složenim podatkovnim strukturama kao što su nizovi i strukture.
Funkcija Malloc() koristi se za dodjelu jednog bloka memorijskog prostora, dok se calloc() u C-u koristi za dodjelu više blokova memorijskog prostora. Svaki blok dodijeljen funkcijom calloc() iste je veličine.
Sintaksa funkcije calloc():
ptr = (cast_type *) calloc (n, size);
Gornja izjava koristi se za dodjelu n memorijskih blokova iste veličine.
Nakon što je memorijski prostor dodijeljen, svi bajtovi se inicijaliziraju na nulu.
Vraća se pokazivač koji je trenutno na prvom bajtu dodijeljenog memorijskog prostora.
Kad god postoji pogreška pri dodjeli memorijskog prostora, kao što je nedostatak memorije, tada se vraća nulti pokazivač.
Primjer calloc():
Program u nastavku izračunava zbroj aritmetičkog niza.
#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; }
Rezultat:
Building and calculating the sequence sum of the first 10 terms
Sum = 45
calloc() u odnosu na malloc(): Ključne razlike
Slijedi ključna razlika između malloc() u odnosu na calloc() u C:
Funkcija calloc() općenito je prikladnija i učinkovitija od funkcije malloc(). Dok se obje funkcije koriste za dodjelu memorijskog prostora, calloc() može dodijeliti više blokova odjednom. Ne morate svaki put zahtijevati memorijski blok. Funkcija calloc() koristi se u složenim podatkovnim strukturama koje zahtijevaju veći memorijski prostor.
Memorijski blok koji dodjeljuje calloc() u C-u uvijek se inicijalizira na nulu, dok u funkciji malloc() u C-u uvijek sadrži vrijednost smeća.
funkcija realloc() u C-u
Pomoću funkcije realloc() u jeziku C možete dodati već dodijeljenu memoriju. Ona proširuje trenutni blok, a izvorni sadržaj ostavlja netaknut. realloc() u jeziku C znači realokacija memorije.
realloc() se također može koristiti za smanjenje veličine prethodno dodijeljene memorije.
Sintaksa funkcije realloc():
ptr = realloc (ptr,newsize);
Gornja izjava dodjeljuje novi memorijski prostor s određenom veličinom u varijabli newsize. Nakon izvršenja funkcije, pokazivač će se vratiti na prvi bajt memorijskog bloka. Nova veličina može biti veća ili manja od prethodne memorije. Ne možemo biti sigurni hoće li novododijeljeni blok pokazivati na istu lokaciju kao prethodni memorijski blok. Ova funkcija će kopirati sve prethodne podatke u novu regiju. Osigurava da će podaci ostati sigurni.
Primjer 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; }
Kad god realloc() u C rezultira neuspješnom operacijom, vraća nulti pokazivač, a prethodni podaci se također oslobađaju.
Dinamički nizovi u C
Dinamičko polje u C-u omogućuje povećanje broja elemenata prema potrebi. C Dinamički niz naširoko se koristi u algoritmima računalne znanosti.
U sljedećem programu stvorili smo i promijenili veličinu dinamičkog niza 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); }
Rezultat programa C Dynamic array na ekranu:
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


