Concetti Chiave
- Le funzioni malloc() e calloc() servono per allocare blocchi di memoria contigui, con calloc() che inizializza i bit a zero.
- Entrambe le funzioni restituiscono un puntatore void* al primo byte di memoria, da utilizzare con un cast, e consentono l'accesso come un array.
- La funzione free() dealloca la memoria dinamica, rendendola disponibile per altre allocazioni e prevenendo problemi di memoria poiché il C non ha un garbage collector.
- La funzione realloc() modifica dinamicamente la dimensione dell'area di memoria puntata, potendo aumentare o diminuire lo spazio allocato.
- Il comportamento delle funzioni di gestione della memoria può essere non definito se i puntatori passati non sono validi o sono già stati deallocati.
Funzioni di gestione dinamica della memoria
Allocazione della memoria
void *malloc ( size_t size ); //blocco contiguo di dimensione size
void *calloc ( size_t nmemb , size_t size ); //blocco contiguo di dimensione nmemb*size
La differenza tra le due funzioni è con l’utilizzo della funzione calloc() inizializza tutti i bit di memoria adibiti alla variabili a 0.
Restituiscono un puntatore void* al primo byte di memoria, ma per usare quella memoria è necessario effettuare un cast. Poichè array e puntatori si comportano allo stesso modo, si può accedere alla memoria allocata dinamicamente come fosse array.
Deallocazione della memoria
void free(void *ptr);
la funzione usata per rilasciare la memoria allocata dinamicamente, disponibile in seguito per altre allocazioni.
Se ptr:
- punta a NULL, la funzione non fa nulla
- è un puntatore non valido, quindi non punta ad un indirizzo di memoria di malloc(), calloc(), realloc() o la variabile è già stata deallocata, il comportamento è non definito
È utile liberare memoria allocata dinamicamente quando non è più necessaria, poiché il C non ha un garbage collector (modalità automatica che gestisce la memoria, nel quale il compilatore libera autonomamente la memoria non più utilizzata).
Modifica della dimensione di memoria
void *realloc(void *ptr, size_t size);
La funzione usata per modificare la dimensione della memoria puntata da ptr nella dimensione specificata da size, la dimensione può sia aumentare sia diminuire. Se ptr:
- è NULL, realloc() è uguale a malloc()
- punta ad un indirizzo non valido, il comportamento è non definito
- punta ad un indirizzo valido e la dimensione size è minore della precedente, la funzione ritorna ptr
- punta ad un indirizzo valido e la dimensione size è maggiore della precedente, la funzione può:
-- Ritornare ptr, se si può estendere in modo contiguo la memoria
-- Ritornare un nuovo indirizzo di memoria (il blocco viene ricopiato in una nuova locazione)
-- Ritornare NULL se non è possibile allocare contiguamente la memoria richiesta
- punta ad un indirizzo valido e la dimensione è 0, realloc() è uguale a free()
Domande da interrogazione
- Qual è la differenza principale tra le funzioni malloc() e calloc()?
- Cosa succede se si chiama free() su un puntatore che punta a NULL?
- Come si comporta realloc() quando la dimensione specificata è maggiore della precedente?
La differenza principale è che calloc() inizializza tutti i bit di memoria a 0, mentre malloc() no.
Se ptr punta a NULL, la funzione free() non fa nulla.
Se la dimensione è maggiore, realloc() può ritornare lo stesso puntatore se la memoria può essere estesa contiguamente, un nuovo indirizzo se il blocco viene ricopiato, o NULL se non è possibile allocare la memoria richiesta.