Memoria e puntatori

In questo capitolo vediamo come è fatta, e come viene usata, la memoria. La memoria si può vedere come un array di byte, in cui ogni variabile occupa un certo numero di byte consecutivi. In C, è possibile determinare sia quanto spazio occupa una variabile, sia la sua posizione in questo vettore. In particolare, è possibile memorizzare la posizione (indirizzo) di una variabile in un'altra variabile. Le variabili che contengono indirizzi di memoria sono dette variabili puntatori.

La memoria

  1. come si rappresenta la memoria ad alto livello
  2. rappresentazione più precisa, come vettore di celle
  3. un esempio di alcune variabili in memoria

Indirizzo, byte occupati e valore di una variabile

  1. variabile = insieme di celle consecutive
  2. per sapere quali celle sono occupate da una variabile, ci basta sapere quante sono e l'indirizzo della prima
  3. ci sono casi in cui serve sapere queste cose
  4. operatori & e sizeof
  5. indirizzo e numero di byte si possono anche stampare
  6. differenza fra valore e indirizzo
  7. sizeof dipende solo dal tipo; per questa ragione, si può usare anche sul tipo

Puntatori

  1. gli indirizzi non sono esattamente dei numeri
  2. per esempio, int p, a; e poi p=&a; genera un errore (warning)
  3. il tipo di un indirizzo non è int
  4. l'indirizzo di una variabile int è di tipo int *
  5. quindi, int *p; int a; e poi p=&a; non genera errori

Dichiarazioni di variabili di tipo puntatore

  1. quando si dichiarano più variabili puntatori insieme, * va ripetuto su tutte
  2. tranne quando si usa typedef

Valore e indirizzo

  1. tutte le variabili hanno valore e indirizzo
  2. questo vale anche per i puntatori
  3. per i puntatori, sono entrambi indirizzi di memoria
  4. sono comunque due cose diverse

Usare l'oggetto puntato

  1. se p è un puntatore, allora *p è come se fosse una variabile
  2. esempio di uso dell'operatore *
  3. cosa succede in memoria quando si esegue un programma con puntatori
  4. rappresentazione degli indirizzi con freccie

Tipo dei puntatori

  1. perchè i puntatori non sono interi?
  2. perchè altrimenti non so in che modo *p va interpretato (è un intero? un carattere?)
  3. alternativa possibile ma non usata: * con due argomenti

Copia del valore e copia dell'indirizzo

  1. differenza fra b=a e p=&a, in pratica
  2. b=a significa: copia il valore di a in b; non ci sono più relazioni fra a e b dopo la copia
  3. p=&a copia l'indirizzo: anche se è una copia, ora *p e a sono la stessa cosa
  4. cosa succede in memoria

Puntatori indefiniti

  1. i puntatori sono inizialmente indefiniti, come tutte la variabili
  2. cosa succede quando si usa un puntatore indefinito
  3. non si devono usare puntatori indefiniti

Allocazione di memoria

  1. quali zone di memoria si possono usare (riservate ad uso esclusivo del programma)
  2. funzione malloc: dà una zona di memoria con queste caratteristiche
  3. esempio di creazione di memoria per contenere un intero
  4. vale ancora la regola che *p è una variabile intera, ma si può usare solo se questa zona di memoria è stata riservata

Il valore NULL

  1. in un puntatore si può mettere il valore 0
  2. il programma non può usare la zona di memoria che inizia dalla posizione 0
  3. questo valore viene denotato con NULL
  4. indica che il puntatore non contiene un indirizzo valido
  5. malloc ritorna questo valore se l'allocazione è fallita

Zone di memoria inaccessibili

  1. il valore iniziale della memoria è indeterminato
  2. se non si perde l'indirizzo di una zona di memoria allocata con malloc, non la si può più usare

Passaggio di un puntatore a una funzione

  1. si può passare l'indirizzo di una variabile a una funzione
  2. effetti della modifica a) del valore della zona di memoria puntata, e b) del valore del parametro formale stesso
  3. cosa succede in memoria

Puntatori a puntatori

  1. i puntatori sono variabili come tutte le altre
  2. quindi, si può determinare il loro indirizzo
  3. differenza fra indirizzo e valore