Articles

Allocazione dinamica della memoria in C: funzioni malloc(), calloc()

Prima di imparare l’allocazione dinamica della memoria in C, cerchiamo di capire:

Come funziona la gestione della memoria in C?

Quando si dichiara una variabile usando un tipo di dati di base, il compilatore C alloca automaticamente lo spazio di memoria per la variabile in un pool di memoria chiamato stack.

Per esempio, una variabile float prende tipicamente 4 byte (secondo la piattaforma) quando viene dichiarata. Possiamo verificare questa informazione usando l’operatore sizeof 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 è allocato in blocchi contigui di memoria, ogni blocco ha la dimensione di un elemento:

#include <stdio.h>int main() { float arr;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 imparato finora, quando si dichiara un tipo di dati di base o un array, la memoria viene gestita automaticamente. Tuttavia, c’è un processo di allocazione della memoria in C che vi permetterà di implementare un programma in cui la dimensione dell’array non è decisa fino a quando non si esegue il programma (runtime). Questo processo è chiamato “allocazione dinamica della memoria”.

In questo tutorial, imparerai-

  • Come funziona la gestione della memoria in C?
  • Allocazione dinamica della memoria in C
  • Funzione C malloc()
  • La funzione free()
  • Funzione C calloc()
  • calloc() vs. malloc(): Differenze chiave
  • Funzione C realloc()
  • Array dinamici

Allocazione dinamica della memoria in C

L’allocazione dinamica della memoria è l’allocazione manuale e la liberazione della memoria secondo le esigenze di programmazione. La memoria dinamica è gestita e servita con puntatori che puntano allo spazio di memoria appena allocato in un’area che chiamiamo heap.

Ora potete creare e distruggere un array di elementi dinamicamente a runtime senza problemi. Per riassumere, la gestione automatica della memoria usa lo stack, e l’allocazione dinamica della memoria C usa l’heap.

La libreria <stdlib.h> ha funzioni responsabili della gestione dinamica della memoria.

Funzione Scopo
malloc() Alloca la memoria della dimensione richiesta e restituisce il puntatore al primo byte dello spazio allocato.
calloc() Alloca lo spazio per gli elementi di un array. Inizializza gli elementi a zero e restituisce un puntatore alla memoria.
realloc() Si usa per modificare la dimensione dello spazio di memoria precedentemente allocato.
Free() Libera o svuota lo spazio di memoria precedentemente allocato.

Discutiamo le funzioni di cui sopra con la loro applicazione

Funzione C malloc()

La funzione C malloc() sta per allocazione di memoria. È una funzione che viene utilizzata per allocare dinamicamente un blocco di memoria. Essa riserva uno spazio di memoria di dimensioni specificate e restituisce il puntatore nullo che punta alla posizione di memoria. Il puntatore restituito è solitamente di tipo void. Ciò 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 tipo 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 dello spazio riservato è assegnato al puntatore ptr di tipo int.

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

Output:

Value of the 6th integer is 480

  1. Nota che sizeof(*ptr) è stato usato al posto di sizeof(int) per rendere il codice più robusto quando la dichiarazione *ptr viene tipografata in un diverso tipo di dati successivamente.
  2. L’allocazione può fallire se la memoria non è sufficiente. In questo caso, restituisce un puntatore NULL. Quindi, dovreste includere del codice per controllare la presenza di un puntatore NULL.
  3. Tenete a mente che la memoria allocata è contigua e può essere trattata come un array. Possiamo usare l’aritmetica dei puntatori per accedere agli elementi dell’array piuttosto che usare le parentesi. Consigliamo di usare + per riferirsi agli elementi della matrice perché usando l’incremento ++ o += cambia l’indirizzo memorizzato dal puntatore.

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

La funzione free()

La memoria per le variabili viene automaticamente deallocata al momento della compilazione. Nell’allocazione dinamica della memoria, dovete deallocare la memoria esplicitamente. Se non lo si fa, si può incorrere in un errore di esaurimento della memoria.

La funzione free() è chiamata per rilasciare/deallocare la memoria in C. Liberando la memoria nel vostro programma, ne rendete più disponibile per l’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);}

Output

 Value of the 2nd integer is 50

Funzione C calloc()

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

La funzione Malloc() è usata per allocare un singolo blocco di memoria mentre la calloc() in C è usata per allocare blocchi multipli di memoria. Ogni blocco allocato dalla funzione calloc() ha la stessa dimensione.

Sintassi della funzione calloc():

ptr = (cast_type *) calloc (n, size);
  • La dichiarazione precedente è usata per allocare n blocchi di memoria della stessa dimensione.
  • Dopo che lo spazio di memoria è allocato, tutti i byte sono inizializzati a zero.
  • Il puntatore che è attualmente al primo byte dello spazio di memoria allocato viene restituito.

Qualora ci sia un errore nell’allocazione dello spazio di memoria, come la scarsità di memoria, allora viene restituito un puntatore nullo.

Esempio di calloc():

Il programma sottostante 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 termsSum = 45

calloc() vs. malloc(): Differenze chiave

Di seguito la differenza chiave tra malloc() Vs calloc() in C:

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 è necessario richiedere un blocco di memoria ogni volta. La funzione calloc() è usata in strutture di dati complesse che richiedono uno spazio di memoria maggiore.

Il blocco di memoria allocato da una calloc() in C è sempre inizializzato a zero mentre nella funzione malloc() in C, contiene sempre un valore garbage.

Funzione C realloc()

Utilizzando la funzione C realloc(), è possibile aggiungere altre dimensioni alla memoria già allocata. Espande il blocco corrente lasciando il contenuto originale così com’è. realloc() in C sta per riallocazione della memoria.

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

Sintassi della funzione realloc():

ptr = realloc (ptr,newsize);

La dichiarazione precedente alloca un nuovo spazio di memoria con una dimensione specificata nella variabile newsize. Dopo aver eseguito la funzione, il puntatore verrà restituito al primo byte del blocco di memoria. La nuova dimensione può essere più grande o più piccola della memoria precedente. Non possiamo essere sicuri che il blocco appena allocato punterà alla stessa posizione del blocco di memoria precedente. Questa funzione copierà tutti i dati precedenti nella nuova regione. Si assicura 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;} 

Quando la funzione realloc() in C risulta in un’operazione non riuscita, restituisce un puntatore nullo, e anche i dati precedenti vengono liberati.

Array dinamici in C

Un array dinamico in C permette al numero di elementi di crescere secondo necessità. Gli array dinamici in C sono ampiamente usati negli algoritmi dell’informatica.

Nel seguente programma, 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; for (i = 0; i < elements; i++) printf("arr_dynamic=%d\n", i, arr_dynamic); 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; for (i = 0; i < elements; i++) printf("arr_dynamic=%d\n", i, arr_dynamic); free(arr_dynamic); } 

Risultato del programma C Dynamic array sullo schermo:

 arr_dynamic=0arr_dynamic=1After reallocarr_dynamic=0arr_dynamic=1arr_dynamic=2arr_dynamic=3

Sommario

  • Possiamo gestire dinamicamente la memoria creando blocchi di memoria come necessario nell’heap
  • In C Dynamic Memory Allocation, la memoria viene allocata a tempo di esecuzione.
  • L’allocazione dinamica della memoria permette di manipolare stringhe e array la cui dimensione è flessibile e può essere cambiata in qualsiasi momento del programma.
  • È necessaria quando non si ha idea di quanta memoria una particolare struttura stia per occupare.
  • Malloc() in C è una funzione di allocazione dinamica della memoria che sta per allocare blocchi di memoria con la dimensione specifica inizializzata ad un valore garbage
  • Calloc() in C è una funzione di allocazione contigua della memoria che alloca più blocchi di memoria alla volta inizializzati a 0
  • Realloc() in C è usata per riallocare la memoria secondo la dimensione specificata.
  • La funzioneFree() è usata per cancellare la memoria allocata dinamicamente.

Lascia una risposta

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *