Riassunti
Appunti universitari in formato Markdown da Obsidian.
Gestione della memoria
download Scarica MDPuntatori
Le variabili puntatore contengono indirizzi di memoria di altre variabili. Mentre le variabili normali contengono un valore diretto (Riferimento Diretto), i puntatori contengono l'indirizzo di una variabile che ha uno specifico valore (Riferimento Indiretto) .
Dichiarazione:
Si usa il simbolo * tra il tipo e il nome.
int *ptr;(Puntatore a un intero).- Attenzione: in dichiarazioni multiple l'asterisco va ripetuto:
int *ptr1, *ptr2;.
Operatori Fondamentali:
- Indirizzo (
&): Restituisce l'indirizzo di memoria della variabile.- Es.
ptr = &x;(Assegna aptrl'indirizzo dix).
- Es.
- *Dereferenziazione (``):** Restituisce il valore dell'oggetto puntato (accede al contenuto all'indirizzo).
- Es.
cout << *ptr;(Stampa il valore della variabile puntata daptr). - Nota:
*e&sono operatori inversi:*&y == y.
- Es.
Puntatori Nulli: Possono essere inizializzati a 0, NULL o nullptr (C++11). Dereferenziare un puntatore nullo causa un errore di Segmentation Fault (crash del programma).
Puntatori Pendenti (Dangling Pointers): Un puntatore che punta a un'area di memoria non più valida (es. una variabile locale uscita dallo scope). Dereferenziarlo causa comportamento indefinito.
Puntatori e Costanti (const)
Il qualificatore const modifica il comportamento del puntatore:
-
Puntatore a Costante: Il valore puntato non può cambiare, ma il puntatore può cambiare indirizzo.
const int *ptr = &x;*ptr = 5;-> ERROREptr = &y;-> OK.
-
Puntatore Costante: L'indirizzo contenuto nel puntatore non può cambiare, ma il valore puntato sì. Deve essere inizializzato subito.
int * const ptr = &x;ptr = &y;-> ERRORE*ptr = 5;-> OK.
-
Puntatore Costante a Costante: Né l'indirizzo né il valore possono cambiare.
const int * const ptr = &x;.Riferimenti (References)
Un riferimento è un alias (un altro nome) per una variabile esistente.
- Sintassi:
int &ref = x;. - Qualsiasi operazione su
refha effetto sux.
Regole e Differenze con i Puntatori:
- Deve essere inizializzato alla dichiarazione.
- Non può essere
NULL. - Non può essere cambiato per riferirsi a un'altra variabile dopo l'inizializzazione (non si può "reseatare").
Aritmetica dei Puntatori
Operazioni valide sui puntatori (utili soprattutto con gli array):
- Incremento/Decremento (
++,--): Sposta il puntatore alla locazione di memoria successiva/precedente in base alla dimensione del tipo di dato.- Es. Se
intoccupa 4 byte eptrè3000,ptr++diventa3004.
- Es. Se
- Somma/Sottrazione Intero (
+,-): Sposta il puntatore di N posizioni. - Differenza tra Puntatori: Restituisce il numero di elementi tra due indirizzi.
- Relazione Array-Puntatori: Il nome di un array è un puntatore costante al primo elemento.
V[i]è equivalente a*(V + i).Memoria Dinamica (Heap)
La memoria allocata staticamente (es.
int A[10]) è decisa a tempo di compilazione. Per decidere la quantità di memoria a tempo di esecuzione, si usa lo Heap (Free Store).Operatore
newAlloca memoria nello Heap e restituisce un puntatore.
- Incremento/Decremento (
- Variabile singola:
int *p = new int(5);(alloca e inizializza a 5). - Array dinamico:
int *arr = new int[dimensione];.Operatore
deleteDealloca la memoria per evitare Memory Leaks (perdita di memoria).
- Variabile singola:
delete p;. - Array dinamico:
delete[] arr;(fondamentale le parentesi quadre!).
Errori Comuni:
- Memory Leak: Dimenticare
delete(la memoria rimane occupata fino al termine del programma). - Double Free: Applicare
deletedue volte sullo stesso puntatore. - Accesso dopo Delete: Usare un puntatore dopo aver liberato la memoria (il puntatore è dangling).
Matrici Dinamiche
Si realizzano come array di puntatori (puntatore a puntatore).
- Allocazione array di puntatori (righe):
int **M = new int*[righe]; - Allocazione di ogni riga:
M[i] = new int[colonne];. - Deallocazione inversa: prima le righe (
delete[] M[i]), poi l'array di puntatori (delete[] M) .