nikpez di nikpez
Ominide 738 punti

Allocazione dinamica

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.

“Oggetti” dinamici

In C/C++ è il programmatore che decide la loro creazione e distruzione.
Area di memoria: Heap
#define NULL 0 in <stdio>
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 <stdlib> si trova: typedef unsigned size_t;

Allocazione/creazione di oggetti dinamici
 #include <stdlib>
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));

Deallocazione/distruzione di oggetti dinamici

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.

Tecniche di recupero della memoria (heap)

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, …)

C++
Operatori:
new
delete
delete [ ]
Esempi:
punt = new tipoDiDato;
delete punt;
puntVett = new tipoDiDato [const|var];
delete [ ] puntVett;

Esempio

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 < numElem; i++)
{
gets((p+i)  nome);
….
}
}
}

Problemi relativi alla programmazione tramite puntatori

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.

Registrati via email