Zusammenfassungen
Universitätsnotizen im Markdown-Format aus Obsidian.
Gestione della memoria
download MD herunterladenPuntatori
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) .