Allocazione dinamica della memoria con la funzione malloc in C

Il linguaggio di programmazione C, oltre a permettere di dichiarare variabili con dimensioni fisse, mette a disposizione delle funzioni per poter gestire in maniera esplicita la memoria del sistema. Uno dei vantaggi del linguaggio C, cosa che lo rende anche più complesso, è il fatto di poter allocare in maniera dinamica lo spazio in memoria. Questa caratteristica permette di creare programmi altamente efficienti, in quanto viene utilizzata solamente lo spazio di memoria strettamente necessario per il funzionamento.

L’allocazione dinamica della memoria risulta essere molto utile soprattutto con l’utilizzo di array, infatti in questo modo non c’è bisogno di dichiarare a priori un array con una dimensione fissa, ma la sua dimensione viene adeguata in base all’utilizzo dell’array stesso.

Struttura della memoria (stack e heap)

Prima di proseguire con la spiegazione della funzione malloc, è doveroso illustrare brevemente la struttura ed il funzionamento base della memoria.
In particolare, le due zone principali della memoria che ci interessano sono due: lo stack e l’heap.

Lo stack è lo spazio di memoria che "cresce" verso il basso, in cui vengono aggiunti o rimossi dati secondo l’ordine LIFO (last in first out), ovvero l’ultimo dato ad essere stato aggiunto sarà anche il primo ad essere rimosso (come una pila di piatti). Questo spazio di memoria è statica, nel senso che contiene ad esempio variabili la cui dimensione è nota a tempo di compilazione, infatti questo spazio viene gestito automaticamente dal compilatore.

Mentre l’heap è lo spazio di memoria che "cresce" verso l’alto, in cui lo spazio allocato non è per forza contiguo, ma assume una struttura casuale in base alla disponibilità dello spazio richiesto. A differenza dello stack, l’heap rappresenta uno spazio dinamico della memoria che viene usato per dichiarare variabili a runtime, questo significa che permette di cambiare le dimensioni assegnate precedentemente alle variabili. A differenza di altri linguaggi di programmazione, nel C questo spazio di memoria viene completamente gestito dal programmatore. Se da un lato favorisce lo sviluppo di programmi altamente efficienti, dall’altro lato può causare gravi errori durante l’esecuzione del programma per la mancata o erronea gestione della memoria dinamica.

Nota: un comune errore che viene effettuato dopo aver allocato dinamicamente uno spazio di memoria, è la mancata liberazione di questo spazio al termine dell’esecuzione del programma. Infatti, come accennato nel paragrafo precedente, la parte dell’heap viene gestita completamente dal programmatore, di conseguenza se viene allocato uno spazio in memoria, questo spazio dovrà essere deallocato prima del termine del programma in modo da liberare l’area in memoria. Questo può essere effettuato tramite l’utilizzo della funzione free().

Funzione malloc in C

Per allocare dinamicamente la memoria in C, si può far uso principalmente di due funzioni, la funzione malloc e la funzione calloc, quest’ultima verrà spiegata nella pagina successiva. Per quanto riguarda la funzione malloc, per poterla utilizzare dobbiamo includere nel header del file la libreria stdlib.h, mentre la sua sintassi è la seguente:void *malloc(size_t size);

dove size indica la dimensione di memoria in byte da allocare, inoltre la funzione restituisce, in caso di successo, un puntatore all’inizio dello spazio allocato, mentre in caso di errore restituisce NULL.

Nota: La funzione malloc non inizializza lo spazio allocato, questo significa che se andiamo a leggere il contenuto del blocco di memoria, sarà indefinito, ovvero conterrà dei valori arbitrari. Mentre, ad esempio la funzione calloc, oltre ad allocare lo spazio di memoria, inizializza ogni byte a 0.

Esempio di utilizzo della funzione malloc in C

Di seguito viene riportato un esempio di utilizzo della funzione malloc in C, in particolare dichiariamo una variabile di tipo int, che verrà utilizzata come array, ma senza indicarne la sua dimensione. Nello specifico il programma chiede all’utente di indicare il valore della dimensione dell’array, che solamente a questo punto verrà allocato dinamicamente nella memoria. Dato che la funzione malloc richiede in input la dimensione in byte dello spazio da allocare, per ottenere questo valore facciamo uso della funzione sizeof, che restituisce la dimensione in byte del tipo di dato passato.
A questo punto chiediamo all’utente di inserire i valori da tastiera e successivamente il programma stampa il contenuto dell’array. Una volta sicuri di non dover più utilizzare la variabile allocata dinamicamente, liberiamo lo spazio allocato nella memoria, usando la funzione free.



#include <stdio.h>
#include <stdlib.h>

int main(){
    int *valori, dim;
    
    printf("Dimensione array: ");
    scanf("%d", &dim);
    
    valori = malloc(sizeof(int) * dim);
    
    if(valori == NULL){
        printf("Errore durante allocazione memoria!\n");
        return -1;
    }
    
    for(int i=0; i<dim; i++){
        printf("Inserisci valore in posizione %d: ", i);
        scanf("%d", &valori[i]);
    }
    
    printf("\n\n");
    printf("Ecco i valori contenuti nell'array:\n");
    
    for(int i=0; i<dim; i++){
        printf("%d ", valori[i]);
    }
    
    free(valori);

   return 0;
}


Dimensione array: 3 Inserisci valore in posizione 0: 6 Inserisci valore in posizione 1: 2 Inserisci valore in posizione 2: 9 Ecco i valori contenuti nell'array: 6 2 9

Indice pagine linguaggio C: