Concetti Chiave

  • L'allocazione dinamica della memoria in C/C++ avviene durante l'esecuzione del programma tramite funzioni come malloc() e calloc().
  • Il programmatore ha la responsabilità di gestire la creazione e la distruzione degli oggetti dinamici, utilizzando funzioni come free() e realloc().
  • È importante azzerare i puntatori dopo la deallocazione per evitare riferimenti fluttuanti (dangling references) e problemi di gestione della memoria.
  • C++ introduce operatori come new e delete per gestire l'allocazione e la deallocazione della memoria in modo più semplice rispetto al C.
  • La vita degli oggetti dinamici inizia con la loro allocazione e termina con la deallocazione, evidenziando l'importanza di un'adeguata gestione della memoria.

Introduzione
int a[3]; allocazione statica (viene stabilita dal compilatore)

L’allocazione dinamica della memoria è l’allocazione eseguita durante l’esecuzione del pgm, in base ad esplicite istruzioni scritte nel pgm stesso.

In C/C++ è il programmatore che decide la loro creazione e distruzione.

Area di memoria: Heap

#define NULL 0 in

Operatore unario: sizeof(tipo|var) restituisce la dimensione in byte di un oggetto.

L’operatore sizeof, simile ad una funzione, ritorna un tipo speciale, usato per le dimensioni di memoria: size_t

In si trova: typedef unsigned size_t;

Allocazione/creazione di oggetti dinamici
 #include

void * malloc (size_t dim);

Alloca un blocco di memoria di dim byte

Restituisce un puntatore generico al blocco di memoria (oppure NULL, se non c’è memoria disponibile).

Testare il puntatore (se uguale a NULL chiamare la exit() )

void * calloc (size_t num, size_t size);

Alloca num elementi consecutivi di memoria di dimensione size (inizializzandola a zero).

Serve ad allocare sequenze contigue di aree di memoria (array).

Restituisce un puntatore generico al blocco di memoria (oppure NULL, se non c’è memoria a disposizione).

double * punt, * punt2;

punt = (double *) calloc(10, sizeof(double));

Più interessante:

punt2 = (double *) calloc(var, sizeof(double));

Si può ottenere la stessa cosa anche con la malloc():

punt2 = (double *) malloc(var* sizeof(double));

void free (void * punt);

Rende nuovamente disponibile lo spazio di memoria (il blocco di memoria) puntato da punt. Se punt è uguale a NULL, la free() non fa nulla.

E’ buona norma “azzerare” i puntatori sui quali è stata effettuata una free(), in modo che non puntino più all’area ora libera.

free(punt);

punt = NULL;

realloc()

void * realloc (void * punt, size_t newSize);

Cambia la dimensione (si può solo aumentarla) di un blocco di memoria

allocata.

Per maggiori informazioni consulta l’Help.

La vita di un oggetto dinamico inizia dalla sua creazione(allocazione, malloc(), calloc()) e finisce con la sua distruzione (deallocazione, free()) o alla fine del programma.

Ci sono due tecniche di recupero della memoria:

1) a carico del programmatore (Pascal, C, C++, …)

2) garbage collector (Lisp, Eiffel, Java, …)

Gestione della memoria in C++

C++

Operatori:

new

delete

delete [ ]

Esempi:

punt = new tipoDiDato;

delete punt;

puntVett = new tipoDiDato [const|var];

delete [ ] puntVett;

typedef struct{

char nome [21];

char cognome [25];

char indirizzo [30];

char professione [15];

}persona;

int main()

{

persona * p;

int i;

p=(persona *) malloc (numElem*sizeof(persona));

if(!p)

printf(“Memoria insufficiente\n”);

else

{

for(i=0; i

{

gets((p+i)  nome);

….

}

}

}

Produzione di spazzatura (garbage)

Dangling references (riferimenti fluttuanti/pendenti)

Effetti collaterali

Se in una funzione, dopo aver allocato (nello stack) un puntatore e un’area dinamica (nello heap, assegnando al puntatore l’indirizzo dell’area), dimentichi di deallocare l’area prima che la funzione termini, produci garbage.

Un puntatore che punta a locazioni di memoria non significative prende il nome di dangling reference.

Domande da interrogazione

  1. Cos'è l'allocazione dinamica della memoria e come viene gestita in C/C++?
  2. L'allocazione dinamica della memoria avviene durante l'esecuzione del programma, basandosi su istruzioni scritte nel codice. In C/C++, è il programmatore a decidere la creazione e la distruzione degli oggetti dinamici, utilizzando funzioni come malloc() e free().

  3. Qual è la differenza tra malloc() e calloc()?
  4. La funzione malloc() alloca un blocco di memoria di una dimensione specificata, mentre calloc() alloca un numero di elementi di una certa dimensione, inizializzando la memoria a zero. Entrambe restituiscono un puntatore generico o NULL se non c'è memoria disponibile.

  5. Come si gestisce la deallocazione della memoria in C/C++?
  6. La deallocazione della memoria si gestisce tramite la funzione free(), che rende nuovamente disponibile lo spazio di memoria puntato. È buona norma azzerare il puntatore dopo la deallocazione per evitare riferimenti fluttuanti.

  7. Quali sono le tecniche di recupero della memoria e come differiscono?
  8. Ci sono due tecniche di recupero della memoria: una a carico del programmatore, utilizzata in linguaggi come C e C++, e l'altra gestita da un garbage collector, presente in linguaggi come Lisp e Java. La prima richiede che il programmatore gestisca manualmente la memoria, mentre la seconda automatizza il processo.

Domande e risposte

Hai bisogno di aiuto?
Chiedi alla community