Allocazione dinamica della memoria in C utilizzando le funzioni malloc() e calloc()

Prima di imparare l'allocazione dinamica della memoria C, comprendiamo:

Come funziona la gestione della memoria in C?

Quando dichiari una variabile utilizzando un tipo di dati di base, il compilatore C alloca automaticamente lo spazio di memoria per la variabile in un pool di memoria chiamato pila.

Ad esempio, una variabile float occupa in genere 4 byte (a seconda della piattaforma) quando viene dichiarata. Possiamo verificare queste informazioni utilizzando il file sizeof operatore come mostrato nell'esempio seguente

#include <stdio.h>
int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}

L'output sarà:

 The size of float is 4 bytes

Inoltre, un array con una dimensione specificata viene allocato in blocchi di memoria contigui, ogni blocco ha la dimensione di un elemento:

#include <stdio.h>
int main() { float arr[10];
printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}

Il risultato è:

 The size of the float array with 10 element is 40

Come appreso finora, quando si dichiara un tipo di dato base o un array, la memoria viene gestita automaticamente. Tuttavia, esiste un processo per allocare memoria in C che consentirà di implementare un programma in cui la dimensione dell'array è indecisa finché non si esegue il programma (runtime). Questo processo si chiama “Allocazione dinamica della memoria. "

Allocazione dinamica della memoria in C

Allocazione dinamica della memoria è l'allocazione e la liberazione manuale della memoria in base alle proprie esigenze di programmazione. La memoria dinamica viene gestita e servita con puntatori che puntano allo spazio di memoria appena allocato in un'area che chiamiamo heap.

Ora puoi creare e distruggere una serie di elementi dinamicamente in fase di esecuzione senza problemi. Per riassumere, la gestione automatica della memoria utilizza lo stack e l'allocazione dinamica della memoria C utilizza l'heap.

IL la libreria ha funzioni responsabili della gestione dinamica della memoria.

Funzione Missione
malloc () Alloca la memoria della dimensione richiesta e restituisce il puntatore al primo byte di
spazio assegnato.
calloc() Alloca lo spazio per gli elementi di un array. Inizializza gli elementi a zero e restituisce un puntatore alla memoria.
riallocare() Viene utilizzato per modificare la dimensione dello spazio di memoria precedentemente allocato.
Gratuito() Libera o svuota lo spazio di memoria precedentemente allocato.

Parliamo delle funzioni di cui sopra con la loro applicazione

Funzione malloc() in C

La funzione C malloc() indica l'allocazione della memoria. È una funzione che viene utilizzata per allocare dinamicamente un blocco di memoria. Riserva lo spazio di memoria della dimensione specificata e restituisce il puntatore nullo che punta alla posizione di memoria. Il puntatore restituito è solitamente di tipo void. Significa che possiamo assegnare la funzione C malloc() a qualsiasi puntatore.

Sintassi della funzione malloc():

ptr = (cast_type *) malloc (byte_size);

Qui,

  • ptr è un puntatore di cast_type.
  • La funzione C malloc() restituisce un puntatore alla memoria allocata di byte_size.

Esempio di malloc():

Example: ptr = (int *) malloc (50)

Quando questa istruzione viene eseguita con successo, viene riservato uno spazio di memoria di 50 byte. L'indirizzo del primo byte di spazio riservato è assegnato al puntatore ptr di tipo int.

Consideriamo un altro esempio:

#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));
    }
}

Produzione:

Value of the 6th integer is 480

Funzione malloc() di C

  1. Notare che dimensione(*ptr) è stato usato al posto di dimensione(int) per rendere il codice più robusto quando la dichiarazione *ptr verrà in seguito convertita in un tipo di dati diverso.
  2. L'allocazione potrebbe non riuscire se la memoria non è sufficiente. In questo caso restituisce un puntatore NULL. Quindi, dovresti includere il codice per verificare la presenza di un puntatore NULL.
  3. Tieni presente che la memoria allocata è contigua e può essere trattata come un array. Possiamo usare l'aritmetica dei puntatori per accedere agli elementi dell'array anziché usare le parentesi [ ]. Consigliamo di usare + per fare riferimento agli elementi dell'array perché usare l'incremento ++ o += cambia l'indirizzo memorizzato dal pointer.

La funzione Malloc() può essere utilizzata anche con il tipo di dati carattere e con tipi di dati complessi come le strutture.

funzione free() in C

La memoria per variabili viene deallocato automaticamente in fase di compilazione. Nell'allocazione dinamica della memoria, è necessario deallocare la memoria in modo esplicito. In caso contrario, potresti riscontrare un errore di memoria insufficiente.

Il libero() La funzione viene chiamata per rilasciare/deallocare memoria in C. Liberando memoria nel programma, se ne rende disponibile altra per un uso successivo.

Per esempio:

#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);
}

Produzione:

 Value of the 2nd integer is 50

funzione calloc() in C

La funzione C calloc() sta per contiguous allocation. Questa funzione è usata per allocare più blocchi di memoria. È una funzione di allocazione dinamica della memoria che è usata per allocare la memoria a strutture dati complesse come array e strutture.

La funzione Malloc() viene utilizzata per allocare un singolo blocco di spazio di memoria mentre calloc() in C viene utilizzata per allocare più blocchi di spazio di memoria. Ogni blocco allocato dalla funzione calloc() ha la stessa dimensione.

Sintassi della funzione calloc():

ptr = (cast_type *) calloc (n, size);
  • L'istruzione precedente viene utilizzata per allocare n blocchi di memoria della stessa dimensione.
  • Dopo che lo spazio di memoria è stato allocato, tutti i byte vengono inizializzati a zero.
  • Viene restituito il puntatore che attualmente si trova sul primo byte dello spazio di memoria allocato.

Ogni volta che si verifica un errore nell'allocazione dello spazio di memoria, ad esempio per carenza di memoria, viene restituito un puntatore nullo.

Esempio di calloc():

Il programma seguente calcola la somma di una sequenza aritmetica.

#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;
    }

Risultato:

Building and calculating the sequence sum of the first 10 terms
Sum = 45

calloc() vs. malloc(): differenze chiave

Di seguito è riportata la differenza fondamentale tra malloc() contro calloc() in do:

La funzione calloc() è generalmente più adatta ed efficiente di quella malloc(). Mentre entrambe le funzioni sono usate per allocare spazio di memoria, calloc() può allocare più blocchi in una sola volta. Non devi richiedere un blocco di memoria ogni volta. La funzione calloc() è usata in strutture dati complesse che richiedono più spazio di memoria.

Il blocco di memoria allocato da calloc() in C viene sempre inizializzato a zero mentre nella funzione malloc() in C contiene sempre un valore spazzatura.

funzione realloc() in C

Utilizzando il c riallocare() funzione, è possibile aggiungere più memoria alla memoria già allocata. Espande il blocco corrente lasciando il contenuto originale così com'è. realloc() in C sta per riallocazione della memoria.

realloc() può essere utilizzato anche per ridurre la dimensione della memoria precedentemente allocata.

Sintassi della funzione realloc():

ptr = realloc (ptr,newsize);

L'istruzione precedente alloca un nuovo spazio di memoria con una dimensione specificata nella variabile newsize. Dopo aver eseguito la funzione, il puntatore verrà riportato al primo byte del blocco di memoria. La nuova dimensione può essere maggiore o minore della memoria precedente. Non possiamo essere sicuri che il blocco appena allocato punterà alla stessa posizione di quella del blocco di memoria precedente. Questa funzione copierà tutti i dati precedenti nella nuova regione. Garantisce che i dati rimangano al sicuro.

Esempio di 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;
}

Ogni volta che realloc() in C risulta in un'operazione non riuscita, restituisce un puntatore null e anche i dati precedenti vengono liberati.

Array dinamici in C

Un array dinamico in C consente al numero di elementi di crescere secondo necessità. Gli array dinamici C sono ampiamente utilizzati negli algoritmi informatici.

Nel programma seguente, abbiamo creato e ridimensionato un array dinamico in 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);
    }

Risultato del programma C Dynamic array sullo schermo:

 
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

Sintesi

  • Possiamo gestire dinamicamente la memoria creando blocchi di memoria secondo necessità nell'heap
  • Nell'allocazione dinamica della memoria C, la memoria viene allocata in fase di esecuzione.
  • L'allocazione dinamica della memoria consente di manipolare stringhe e array la cui dimensione è flessibile e può essere modificata in qualsiasi momento nel programma.
  • È necessario quando non hai idea di quanta memoria occuperà una particolare struttura.
  • Malloc() in C è una funzione di allocazione dinamica della memoria che sta per allocazione della memoria che blocca blocchi di memoria con la dimensione specifica inizializzata su un valore spazzatura
  • Calloc() in C è una funzione di allocazione di memoria contigua che alloca più blocchi di memoria alla volta inizializzati a 0
  • Realloc() in C viene utilizzato per riallocare la memoria in base alla dimensione specificata.
  • La funzione Free() viene utilizzata per cancellare la memoria allocata dinamicamente.

Riassumi questo post con: