Alocarea dinamică a memoriei în C folosind funcțiile malloc(), calloc().

Înainte de a învăța C alocare memorie dinamică, să înțelegem:

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 stivui.

De exemplu, o variabilă float are de obicei 4 octeți (în funcție de platformă) când este declarată. Putem verifica aceste informații folosind mărimea operator 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 indecisă până când rulați programul (timpul de rulare). Acest proces se numește „Alocarea dinamică a memoriei. "

Alocarea dinamică a memoriei în C

Alocarea dinamică a memoriei este alocarea manuală și eliberarea memoriei în funcție de nevoile dumneavoastră de programare. Memoria dinamică este gestionată și servită cu pointeri care indică noul spațiu de memorie 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

C malloc() Funcția

  1. Observa asta dimensiunea(*ptr) a fost folosit în loc de dimensiunea(int) pentru a face codul mai robust atunci când declarația *ptr este tipificată mai târziu la un alt tip de date.
  2. 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.
  3. 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ă.

Liberul() funcția este apelată pentru a elibera/dezaloca memorie în C. Eliberând memorie în programul dvs., faceți mai mult 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 C realloc() funcția, puteți adăuga mai multă dimensiune de memorie memoriei deja alocate. Extinde blocul curent, lăsând conținutul original așa cum este. realloc() în C înseamnă 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

Rezumat

  • Putem gestiona în mod dinamic memoria creând blocuri de memorie după cum este necesar în heap
  • În C Dynamic Memory Allocation, memoria este alocată la un timp de rulare.
  • Alocarea dinamică a memoriei permite manipularea șirurilor și matricelor a căror dimensiune este flexibilă și poate fi modificată oricând în programul dumneavoastră.
  • Este necesar atunci când nu aveți idee câtă memorie va ocupa o anumită structură.
  • Malloc() în C este o funcție de alocare dinamică a memoriei, care reprezintă alocarea memoriei care blochează memoria cu dimensiunea specifică inițializată la o valoare de gunoi.
  • Calloc() în C este o funcție de alocare a memoriei contigue care alocă mai multe blocuri de memorie la un moment dat inițializat la 0
  • Realloc() în C este folosit pentru a realoca memoria în funcție de dimensiunea specificată.
  • Funcția Free() este folosită pentru a șterge memoria alocată dinamic.