Alocare dinamică a memoriei în C: malloc(), calloc()
⚡ Rezumat inteligent
Alocarea dinamică a memoriei în C rezervă și eliberează memorie heap în timpul execuției folosind funcțiile malloc(), calloc(), realloc() și free() din biblioteca stdlib.h, permițând programelor să dimensioneze flexibil tablourile și structurile atunci când cerințele sunt necunoscute înainte de execuție.

Cum funcționează gestionarea memoriei în C?
Când declarați o variabilă folosind un tip de date de bază, compilatorul C alocă automat spațiu de memorie pentru variabilă într-un pool de memorie numit stivă.
De exemplu, o variabilă cu număr de tip float are de obicei 4 octeți (în funcție de platformă) atunci când este declarată. Putem verifica aceste informații folosind operatorul sizeof, așa cum se arată în exemplul de mai jos.
#include <stdio.h> int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
Ieșirea va fi:
The size of float is 4 bytes
De asemenea, o matrice cu o dimensiune specificată este alocată în blocuri adiacente de memorie, fiecare bloc având dimensiunea pentru un 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;}
Rezultatul este:
The size of the float array with 10 element is 40
După cum am învățat până acum, atunci când se declară un tip de date de bază sau o matrice, memoria este gestionată automat. Cu toate acestea, există un proces de alocare a memoriei în C care vă va permite să implementați un program în care dimensiunea matricei este nedeterminată până când rulați programul (în timpul execuției). Acest proces se numește „Alocare dinamică a memoriei”.
Alocarea dinamică a memoriei în C
Alocarea dinamică a memoriei este alocarea și eliberarea manuală a memoriei în funcție de nevoile dvs. de programare. Memoria dinamică este gestionată și servită cu pointeri care indică spațiul de memorie nou alocat într-o zonă pe care o numim heap.
Acum puteți crea și distruge o serie de elemente în mod dinamic în timpul execuției, fără probleme. Pentru a rezuma, gestionarea automată a memoriei folosește stiva, iar C Dynamic Memory Allocation folosește heap-ul.
The biblioteca are funcții responsabile pentru gestionarea dinamică a memoriei.
| Funcţie | Scop |
|---|---|
| malloc () | Alocă memoria de dimensiunea cerută și returnează pointerul la primul octet al spatiu alocat. |
| calloc() | Alocă spațiu pentru elementele unui tablou. Inițializează elementele la zero și returnează un pointer în memorie. |
| realloc() | Este folosit pentru a modifica dimensiunea spațiului de memorie alocat anterior. |
| Gratuit() | Eliberează sau golește spațiul de memorie alocat anterior. |
Să discutăm despre funcțiile de mai sus cu aplicația lor
funcția malloc() în C
Funcția C malloc() reprezintă alocare de memorie. Este o funcție care este utilizată pentru a aloca dinamic un bloc de memorie. Rezervă spațiu de memorie de dimensiunea specificată și returnează pointerul nul care indică locația de memorie. Indicatorul returnat este de obicei de tip void. Înseamnă că putem atribui funcția C malloc() oricărui pointer.
Sintaxa funcției malloc():
ptr = (cast_type *) malloc (byte_size);
Aici,
- ptr este un pointer de tip_cast.
- Funcția C malloc() returnează un pointer către memoria alocată pentru byte_size.
Exemplu de malloc():
Example: ptr = (int *) malloc (50)
Când această instrucțiune este executată cu succes, un spațiu de memorie de 50 de octeți este rezervat. Adresa primului octet al spațiului rezervat este atribuită pointerului ptr de tip int.
Luați în considerare un alt exemplu:
#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)); } }
ieșire:
Value of the 6th integer is 480
- Observați că s-a folosit sizeof(*ptr) în loc de sizeof(int) pentru a face codul mai robust atunci când declarația *ptr este convertită ulterior la un tip de date diferit.
- Alocarea poate eșua dacă memoria nu este suficientă. În acest caz, returnează un pointer NULL. Deci, ar trebui să includeți cod pentru a verifica dacă există un pointer NULL.
- Rețineți că memoria alocată este adiacentă și poate fi tratată ca o matrice. Putem folosi aritmetica pointerului pentru a accesa elementele matricei în loc să folosim paranteze [ ]. Vă sfătuim să folosiți + pentru a face referire la elementele matricei, deoarece utilizarea incrementarii ++ sau += modifică adresa stocată de indicatorul.
Funcția Malloc() poate fi utilizată și cu tipul de date caracter, precum și cu tipuri de date complexe, cum ar fi structurile.
funcția free() în C
Memoria pentru variabile este dealocat automat în timpul compilării. În alocarea dinamică a memoriei, trebuie să dealocați memoria în mod explicit. Dacă nu este făcut, este posibil să întâmpinați o eroare de memorie lipsită.
Funcția free() este apelată pentru a elibera/dealoca memorie în C. Prin eliberarea memoriei în program, faci mai multă memorie disponibilă pentru utilizare ulterioară.
De exemplu:
#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); }
ieșire:
Value of the 2nd integer is 50
funcția calloc() în C
Funcția C calloc() reprezintă alocare contiguă. Această funcție este utilizată pentru a aloca mai multe blocuri de memorie. Este o funcție de alocare dinamică a memoriei care este utilizată pentru a aloca memoria unor structuri complexe de date, cum ar fi matrice și structuri.
Funcția Malloc() este folosită pentru a aloca un singur bloc de spațiu de memorie, în timp ce calloc() din C este folosită pentru a aloca mai multe blocuri de spațiu de memorie. Fiecare bloc alocat de funcția calloc() este de aceeași dimensiune.
Sintaxa funcției calloc():
ptr = (cast_type *) calloc (n, size);
Declarația de mai sus este folosită pentru a aloca n blocuri de memorie de aceeași dimensiune.
După ce spațiul de memorie este alocat, toți octeții sunt inițializați la zero.
Este returnat indicatorul care se află în prezent la primul octet al spațiului de memorie alocat.
Ori de câte ori există o eroare la alocarea spațiului de memorie, cum ar fi deficitul de memorie, atunci este returnat un pointer nul.
Exemplu de calloc():
Programul de mai jos calculează suma unei secvențe aritmetice.
#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() vs. malloc(): Diferențele cheie
În continuare este diferența cheie între malloc() vs calloc() în C:
Funcția calloc() este în general mai potrivită și mai eficientă decât cea a funcției malloc(). În timp ce ambele funcții sunt folosite pentru a aloca spațiu de memorie, calloc() poate aloca mai multe blocuri în același timp. Nu trebuie să solicitați un bloc de memorie de fiecare dată. Funcția calloc() este utilizată în structurile de date complexe care necesită spațiu de memorie mai mare.
Blocul de memorie alocat de un calloc() în C este întotdeauna inițializat la zero, în timp ce în funcția malloc() în C, acesta conține întotdeauna o valoare de gunoi.
funcția realloc() în C
Folosind funcția realloc() din C, puteți adăuga mai multă memorie la memoria deja alocată. Aceasta extinde blocul curent, păstrând conținutul original așa cum este. realloc() în C reprezintă realocarea memoriei.
realloc() poate fi folosit și pentru a reduce dimensiunea memoriei alocate anterior.
Sintaxa funcției realloc():
ptr = realloc (ptr,newsize);
Declarația de mai sus alocă un spațiu de memorie nou cu o dimensiune specificată în variabila newsize. După executarea funcției, indicatorul va fi returnat la primul octet al blocului de memorie. Noua dimensiune poate fi mai mare sau mai mică decât memoria anterioară. Nu putem fi siguri că dacă blocul nou alocat va indica aceeași locație cu cea a blocului de memorie anterior. Această funcție va copia toate datele anterioare în noua regiune. Se asigură că datele vor rămâne în siguranță.
Exemplu de 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; }
Ori de câte ori realloc() în C are ca rezultat o operație nereușită, returnează un pointer nul, iar datele anterioare sunt, de asemenea, eliberate.
Matrice dinamice în C
O matrice dinamică în C permite numărului de elemente să crească după cum este necesar. C Matricele dinamice sunt utilizate pe scară largă în algoritmii informaticii.
În programul următor, am creat și redimensionat o matrice dinamică în 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); }
Rezultatul programului C Dynamic matrice pe ecran:
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

