SlideShare a Scribd company logo
1 of 49
Download to read offline
Array dinamici e puntatori
Motivazioni
• Gli oggetti considerati finora devono essere
  completamente definiti (tipo, nome e dimensione) a tempo
  di scrittura del programma
• Ciò non costituisce un problema per gli oggetti di tipo
  primitivo, ma può essere limitativo per oggetti di tipo
  strutturato quali array e stringhe
   – talvolta non è possibile sapere a priori la quantità di dati
      da memorizzare/gestire
• Per superare la rigidità della definizione statica delle
  dimensioni, occorre un modo per “allocare in memoria
  oggetti le cui dimensioni sono determinate durante
  l'esecuzione del programma”
• Questo è possibile grazie al meccanismo di allocazione
  dinamica della memoria

Programmazione I - Paolo Valente, 2008/2009                     2
Memoria libera
• Prima dell'inizio dell'esecuzione di un processo, il sistema
  operativo riserva ad esso un spazio di memoria di
  dimensioni predefinite
   – quello che finora abbiamo chiamato memoria del
     programma
   – locazioni consecutive di memoria (tipicamente da 1
     byte l'una)
• Questo spazio di memoria è a sua volta organizzato in
  segmenti distinti
• Uno di questi segmenti è chiamato
   – memoria libera, memoria dinamica oppure heap
• E' possibile allocare oggetti all'interno della memoria
  dinamica in momenti arbitrari durante l'esecuzione del
  programma
   – ovviamente finché lo spazio non si esaurisce
Programmazione I - Paolo Valente, 2008/2009                      3
Memoria libera
      Indirizzo prima
      locazione della
      memoria libera,
               ad es.:
         0xFFFF0000
                                                  Memoria
                                                  libera


      Indirizzo ultima
       locazione della
      memoria libera,
         mobile (come
           vedremo in
              seguito)
Programmazione I - Paolo Valente, 2008/2009                 4
Allocazione dinamica
• Gli oggetti allocati in memoria dinamica sono detti dinamici
• In questa presentazione considereremo solo array
  dinamici
   – Array allocati in memoria dinamica durante l'esecuzione
     del programma
   – Come vedremo, il numero di elementi non è vincolato ad
     essere definito a tempo di scrittura del programma
• Come si alloca un array dinamico?
   – Mediante l'operatore new
• Come si accede ad un oggetto in memoria dinamica?
   – Come ogni altro oggetto è caratterizzato da un indirizzo
     nello spazio di memoria del processo
   – L'operatore new ritorna l'indirizzo dell'oggetto allocato in
     memoria dinamica
Programmazione I - Paolo Valente, 2008/2009                     5
Operatore new
• Vediamo l'uso dell'operatore new solo per allocare array
      new <nome_tipo> [<num_elementi>] ;

      – Alloca un array di <num_elementi> oggetti di tipo
        <nome_tipo>, non inizializzati (valori casuali)
      – <num_elementi> può essere un'espressione aritmetica
        qualsiasi

• Ad esempio
  new int[10] ; // alloca un array dinamico
                  // di 10 elementi
• Ma possiamo anche scrivere
  int a ; cin>>a;
  new int[a] ; // alloca un array dinamico
                 // di a elementi
Programmazione I - Paolo Valente, 2008/2009                   6
Array dinamico allocato nello heap
            0xFFFF0000


          Indirizzo
             array
       in memoria,                                    Memoria
                                              Array
            ad es.:                                   libera
                                          dinamico
       0xFFFF0008




Programmazione I - Paolo Valente, 2008/2009                     7
Valore di ritorno dell'operatore new
• L'operatore new non ritorna un riferimento (nel senso di
  sinonimo) all'oggetto allocato
• Gli oggetti dinamici sono oggetti senza nome
• Come si fa per accedere a tali oggetti?
      – Come detto, l'operatore new ritorna l'indirizzo
        dell'oggetto allocato
• Possiamo accedere all'oggetto tramite tale indirizzo
• Ma dove lo memorizziamo?
      – Per memorizzare un indirizzo ci serve un oggetto di tipo
        puntatore


Programmazione I - Paolo Valente, 2008/2009                    8
Tipi di dato

                                                           Derivati
      Scalari,
    Fondamentali,
     Primitivi o
     Aritmetici
                                              Riferimenti Strutturati   Puntatori
                                                           array []
                                                           struct
      predefiniti             enumerati
                               enum
        bool
        char
        int
         float
         double

Programmazione I - Paolo Valente, 2008/2009                                    9
Puntatori
• Un oggetto di tipo puntatore ha per valore un indirizzo
  di memoria
• Le definizione di un oggetto puntatore ha la seguente
  forma
     [const] <tipo_oggetto_puntato>
        * [const] <identificat.> [                   = <indirizzo>];
• Il primo qualificatore const è presente se si punta ad
  un oggetto non modificabile
• Il secondo const è presente se il valore del puntatore,
  una volta inizializzato, non può più essere modificato
• Per definire un puntatore inizializzato con l'indirizzo di
  un array dinamico di N elementi:
     int * p = new int [N] ;

Programmazione I - Paolo Valente, 2008/2009                        10
Indirizzo array dinamico
                               0xFFFF0000


             0xFFFF0008
    p

               p è inizializzato con              Array   Memoria
               il valore ritornato da         dinamico    libera
               da new, ossia con
               l'indirizzo dell'array
               dinamico

int * p = new int [N] ;



Programmazione I - Paolo Valente, 2008/2009                   11
Accesso agli elementi
• Accesso agli elementi di un array dinamico
  – Possibile in modo identico agli array statici
  – selezione con indice mediante parentesi
    quadre
  – gli indici partono da 0




Programmazione I - Paolo Valente, 2008/2009         12
Proviamo ...
• Scrivere un programma che
      – Allochi un array dinamico di interi, di dimensioni
        lette da stdin
      – Lo inizializzi
      – Lo stampi
• Soluzione: parte dell'esempio seguente ...




Programmazione I - Paolo Valente, 2008/2009              13
Esempi di accesso agli elementi
main()
{
  int N ;
  cin>>N ;

    int * p = new int [N] ;

    for (int i = 0 ; i < N ; i++)
        p[i] = 0 ; // inizializzazione

    cout<<p[0]<<endl ;

    cin>>p[N] ; // Esempio di: ERRRORE LOGICO
                // E DI ACCESSO ALLA MEMORIA
}
Programmazione I - Paolo Valente, 2008/2009     14
Valori, operazioni, tempo di vita
• Un oggetto di tipo puntatore
   – Ha per valori un sottoinsieme dei numeri naturali
        o un puntatore che contenga 0 (NULL in C) viene

          detto puntatore nullo
   – Prevede operazioni correlate al tipo di oggetto a cui
      punta
        o A PARTE L'ASSEGNAMENTO, NON VEDREMO

          ALTRE OPERAZIONI CON I PUNTATORI
   – Segue le stesse regole di tempo di vita di un
      qualsiasi altro tipo di oggetto
• I riferimenti ad un oggetto di tipo puntatore (compreso
  il riferimento di default, ossia il nome dell'oggetto)
  seguono le stesse regole di visibilità di tutti gli
  identificatori
Programmazione I - Paolo Valente, 2008/2009              15
Tempo di vita di un array dinamico
• Torniamo agli array dinamici
• NON CONFONDETE UN PUNTATORE CON L'ARRAY A
  CUI PUNTA !!!
• Il puntatore serve solo a mettere da parte l'indirizzo
  dell'array per potervi poi accedere in un secondo
  momento
• Una volta allocato, un array dinamico esiste fino alla
  fine del programma (o fino a che non viene deallocato,
  come stiamo per vedere)
   – Anche se non esistesse più il puntatore che contiene il
      suo indirizzo !!!



Programmazione I - Paolo Valente, 2008/2009               16
Puntatore ed array in memoria
                                               Memoria libera



                 0xFFFF0008
        p

                                                   Array
Un puntatore e l'array a cui tale puntatore    dinamico
può puntare hanno tempi di vita
indipendenti, ed occupano zone di
memoria diverse.
In particolare, se non deallocato, un array
dinamico continua ad esistere anche se e
quando il puntatore utilizzato per
memorizzare il suo indirizzo non esiste più.

Programmazione I - Paolo Valente, 2008/2009                17
Deallocazione array dinamico
• Si può deallocare esplicitamente un array dinamico,
  ossia liberare lo spazio da esso occupato nella
  memoria dinamica, mediante l'operatore

     delete[] <indirizzo_oggetto_da_deallocare>




Programmazione I - Paolo Valente, 2008/2009             18
Operatore delete [ ]
• Prende per argomento l'indirizzo dell'array da
  deallocare
  Es.:
  int * p = new int[10] ;
  delete [] p ; // dealloca l'array dinamico
                     // puntato da p
• Può essere applicato solo all'indirizzo di un array
  dinamico allocato con l'operatore new
   – Altrimenti si ha un errore di gestione della memoria
   – Se si è fortunati, l'errore è segnalato durante
     l'esecuzione del programma
• Può essere applicato anche al puntatore nullo, nel
  qual caso non fa nulla e non genera errori

Programmazione I - Paolo Valente, 2008/2009             19
Esempio
main()
 {
   int vector[15]; // spazio per 15 interi
   int *dynVect;   // spazio per il puntatore, non l'array !

     int k ;
      cout<<quot;Inserire la dimensione desiderata del vettorenquot;;
      cin>>k ;
      dynVect = new int [k];
 
      /* ora è possibile usare liberamente sia vector sia
        dynVect come array, lunghi 15 e k, rispettivamente */
 
  for (int i=0;i<k;i++)                       dynVect[i] = i*i;
  for (int i=0;i<15;i++)                      vector[i] = 2*i;

  delete [] dynVect; // necessaria?
 }
Programmazione I - Paolo Valente, 2008/2009                       20
Esercizi
• crea_riempi_distruggi_array.cc




Programmazione I - Paolo Valente, 2008/2009              21
Passaggio alle funzioni
• Passaggio di un array dinamico ad una funzione
      – Possibile in modo identico agli array statici
                Oltre che
            o

                [const]<nome_tipo>      identificatore []
                il parametro formale può essere dichiarato
                [const]<nome_tipo> * identificatore
      – Le dimensioni dell'array passato come parametro
        attuale non sono implicitamente note alla funzione
        chiamata
      – Il passaggio dell'array è per riferimento
      – Usare il qualificatore const se si vuole evitare
        modifiche
Programmazione I - Paolo Valente, 2008/2009                  22
Riferimenti e puntatori 1/2
• Ora possiamo dire cosa viene effettivamente passato ad
  una funzione che prende in ingresso un array, tanto statico
  quanto dinamico
• Le viene passato l'indirizzo dell'array
   – O se vogliamo l'indirizzo del primo elemento
      dell'array
• Quindi le definizioni
  [const]<nome_tipo> identificatore []
  oppure
  [const]<nome_tipo> * identificatore
   sono di fatto definizioni di un parametro formale di tipo
   puntatore
• All'atto della chiamata il parametro formale viene
  inizializzato con l'indirizzo dell'array
Programmazione I - Paolo Valente, 2008/2009                    23
Riferimenti e puntatori 2/2
• A livello di linguaggio non si tratta quindi di un passaggio
  per riferimento, ma di un passaggio per valore
   – Il parametro formale contiene infatti una copia
      dell'indirizzo dell'array
• Ma proprio siccome il parametro formale contiene (una
  copia de) l'indirizzo dell'array, allora tramite il parametro
  formale si accede esattamente all'array il cui indirizzo è
  passato come parametro attuale
• Quindi ogni modifica effettuata all'array puntato dal
  parametro formale si riflette sull'array di cui si è passato
  l'indirizzo
• Ecco perché a livello logico possiamo affermare che si
  tratta a tutti gli effetti di un passaggio per riferimento di un
  array
Programmazione I - Paolo Valente, 2008/2009                       24
Ritorno da parte delle funzioni
• Una funzione può ritornare l'indirizzo di un array
  dinamico

• Il tipo di ritorno deve essere

     [const]             <nome_tipo> *




Programmazione I - Paolo Valente, 2008/2009            25
Esercizio 1 (Specifica)

• Scrivere un programma che utilizzi una
  funzione per leggere da input un certo numero
  di valori int e li inserisca in un array allocato
  dinamicamente dalla funzione stessa.
     La funzione deve restituire al main() il
     puntatore all'array dinamico creato. Stampare
     poi l'array nel main()



Programmazione I - Paolo Valente, 2008/2009          26
Esercizio 1 (Algoritmo della funzione)
• E’ necessario chiedere in input il numero di valori che si
  vogliono inserire
• Si alloca un array dinamico della dimensione richiesta
• Si scandisce tutto il vettore, inserendo elemento per
  elemento


 Esercizio 1 (Rappresentazione informazioni)
• Serve un puntatore a int sia nella funzione sia nel main()
• Serve una variabile int per memorizzare la dimensione presa
  da input
• Serve un int come indice per scandire l'array
Programmazione I - Paolo Valente, 2008/2009                    27
Esercizio 1 (Programma)
int* creaVett(void)
  {
     int num ;
     cout<<“Quanti valori? ”; cin>>num;
     int *v = new int[num] ;
     for (int i=0; i<num; i++)
      { cout<<”v[“<<i<<”]=”; cin>>v[i] ; }
     return v;
                      Non si sa quanti elementi abbia
  }
                                              l'array. Il main() e altre eventuali
                                              funzioni non potrebbero utilizzare
main()
                                              l'array senza sapere la dimensione.
  {
                                              Per poter usare l'array, il programma
    int *pv;
                                              va esteso ...
    pv = creaVett();
    // come si fa
    // a stampare l'array?
    delete [] pv ;
  }
Programmazione I - Paolo Valente, 2008/2009                                      28
Esercizio 1 (Programma corretto)
int* creaVett(int &num)
  {
     cout<<“Quanti valori? ”; cin>>num;
     int *v = new int[num] ;
     for (int i=0; i<num; i++)
     { cout<<”v[“<<i<<”]=”; cin>>v[i] ; }
     return v;
  }

                                              In questo modo, il main() può
main()
                                              accedere propriamente
  {
                                              agli elementi dell'array
    int *pv, dim;
    pv = creaVett(dim);
    for (int i=0; i<dim; i++)
       cout<<pv[i]<<endl ;
    delete [] pv ;
  }
Programmazione I - Paolo Valente, 2008/2009                                   29
Esercizio 1 (Programma alternativo)
void creaVett(int * &v, int &num)
  {
     cout<<“Quanti valori? ”; cin>>num;
     v = new int[num] ;
     for (int i=0; i<num; i++)
     { cout<<”v[“<<i<<”]=”; cin>>v[i] ; }
  }
                               Versione (concettualmente
                               più complessa) con due
main()
                               parametri che riportano sia
  {
                               l'array sia la sua dimensione.
    int *pv, dim;
                               La funzione deve restituire
    creaVett(pv, dim);         l'array attraverso un parametro
    for (int i=0; i<dim; i++) passato per riferimento. Poiché
                               il tipo dell'array è un puntatore
       cout<<pv[i]<<endl ;
                               a int (cioè, int *), il tipo del
    delete [] pv ;
                               parametro è un riferimento a
  }
                               puntatore a int

Programmazione I - Paolo Valente, 2008/2009                    30
Riferimento a puntatore
• Tipo derivato

• Il tipo di partenza è un puntatore

• Definizione

     [const]<nome_tipo>                       * & <identificatore> ;




Programmazione I - Paolo Valente, 2008/2009                            31
Esercizio 2


• Scrivere una funzione vett_copy(...) che
  prenda in ingresso un array di interi, ne crei
  un altro uguale, e ritorni (l'indirizzo del)
  secondo array mediante un parametro di
  uscita (un parametro quindi di tipo riferimento
  a puntatore)




Programmazione I - Paolo Valente, 2008/2009         32
Esercizio 2
void vett_copy(const int* v1, int num,
                 int*& pv2)
 {
     pv2 = new int[num] ;
     for (int i=0; i<num; i++)
          pv2[i] = v1[i];
 }
 main()
   { int vettore[] = {20,10,40,50,30};
      int* newVet = 0 ;
      vett_copy(vettore, 5, newVet);
      delete [] newVet ;
   }
Programmazione I - Paolo Valente, 2008/2009         33
Esempio puntatore ad array costante
main()
{
  int N ;
  cin>>N ;
  int * p = new int [N] ;
  int * q = p ; // q punta allo stesso array
  const int * r = q ; // r punta allo stesso array,
                      // ma tramite r non lo si potrà
                      // modificare
  cin>>q[0] ; // corretto
  cin>>r[0] ; // errore segnalato a tempo di
              // compilazione: non si può utilizzare
              // r per cambiare valore all'array
}


Programmazione I - Paolo Valente, 2008/2009             34
Esempio puntatore costante
main()
{
  int N ;
  cin>>N ;
  int *p ;

    p = new int [N] ;
    int * const s = p ; // s punta allo stesso array
                        // e non potrà cambiare valore
    p = new int [N] ; // d'ora in poi p punta ad un
                      // diverso array, l'unico
                      // riferimento al precedente è
                      // rimasto s
    s = p ; // ERRORE: s non può cambiare valore

}

Programmazione I - Paolo Valente, 2008/2009              35
Riassunto qualificatore const
• Un puntatore ad array dinamico costante non può
  essere utilizzato per modificare il valore degli elementi
  dell'array
• Una variabile di tipo puntatore può essere
  (ri)assegnata in ogni momento
      – Una costante di tipo puntatore invece può essere
        solo inizializzata
      – Questo può evitare gli errori pericolosi che
        vedremo tra qualche slide




Programmazione I - Paolo Valente, 2008/2009                36
Flessibilità e problemi seri
• Una variabile di tipo puntatore è come una variabile di
  un qualsiasi altro tipo
• Quindi può essere utilizzata anche se non
  inizializzata !!!!
   – Errore logico e di accesso/gestione della memoria
• Inoltre può essere (ri)assegnata in ogni momento
• Infine più di un puntatore può puntare allo stesso
  oggetto
   – Quindi possono esservi effetti collaterali
• Ma anche di peggio ...



Programmazione I - Paolo Valente, 2008/2009             37
Problema serio: dangling reference
• Dangling reference (pending pointer)
   – Si ha quanto un puntatore punta ad una locazione
     di memoria in cui non è presente alcun oggetto
     allocato
   – Tipicamente accade perché il puntatore non è stato
     inizializzato, o perché l'oggetto è stato deallocato




Programmazione I - Paolo Valente, 2008/2009             38
Puntatore non inizializzato
main()
{
  int N ;
  cin>>N ;
  int *p ; // p contiene un valore casuale

    cin>>p[0] ; //                 ERRORE LOGICO E DI GESTIONE DELLA
                //                 MEMORIA: p non è stato
                //                 inizializzato/assegnato
                //                 all'indirizzo di alcun array
                //                 dinamico
}




Programmazione I - Paolo Valente, 2008/2009                        39
Oggetto deallocato
main()
{
  int N ;
  cin>>N ;
  int * p = new int [N] ;
  delete [] p ;
  cout<<p[0]<<endl ; // ERRRORE LOGICO
                     // E DI ACCESSO ALLA MEMORIA
}




Programmazione I - Paolo Valente, 2008/2009         40
Per ridurre i problemi
• Ovunque possibile, utilizzare perlomeno puntatori
  costanti
  Es:
  int dim ;
  cin>dim ;
  int * const p = new int[dim] ;
• Così siamo costretti ad inizializzarli e non possiamo
  riassegnarli ad altri array o magari a puntatori
  pendenti




Programmazione I - Paolo Valente, 2008/2009               41
Esaurimento memoria
• In assenza di memoria libera disponibile, l'operatore
  new fallisce
   – viene generata una eccezione
   – se non gestita, viene stampato un messaggio di
     errore ed il programma termina
• Se si vuole, si può
   – gestire l'eccezione
   oppure
   – “agganciare” il fallimento dell'operatore ad una
     propria funzione
      o Tale funzione verrà invocata in caso di fallimento

• Non vedremo nessuna delle due soluzioni, quindi i
  nostri programmi semplicemente termineranno in
  caso di esaurimento della memoria
Programmazione I - Paolo Valente, 2008/2009             42
Problema serio: memory leak
• Esaurimento inaspettato della memoria causato da
  mancata deallocazione di oggetti non più utilizzati
   – Spesso correlato con la perdita di riferimenti
     all'oggetto stesso




Programmazione I - Paolo Valente, 2008/2009             43
Esempio di memory leak
void fun()
{
  int N ;
  cin>>N ;
  int * p = new int [N] ;
}
main()
{
  fun() ;
  // nel main p non è visibile, ma una volta invocata
  // fun(), l'array rimane in memoria; inoltre, una
  // volta terminata fun() si è perso ogni
  // riferimento all'array, quindi, tra l'altro, non
  // si può più deallocarlo !
  ...
}
Programmazione I - Paolo Valente, 2008/2009             44
Stringhe dinamiche
• E’ possibile allocare array dinamici di oggetti
  di qualsiasi tipo
      – Come si alloca una stringa dinamica?
      – Come si alloca una array di struct?




Programmazione I - Paolo Valente, 2008/2009         45
Allocazione stringa dinamica
• Stringa di 10 caratteri:
            char * const str                  =   new char[11] ;

• Stringa di dimensione definita da stdin:
            int dim ;
            cin>>dim ;
            char * const str                  = new char[dim+1];




Programmazione I - Paolo Valente, 2008/2009                        46
Allocazione di array di struct

            struct persona
               {
                 char nome_cognome[41];
                 char codice_fiscale[17];
                 float stipendio;
               };
            persona * const t = new persona[10] ;




Programmazione I - Paolo Valente, 2008/2009         47
Matrici dinamiche
• Una matrice è un array di array
• Quindi una matrice dinamica è un array dinamico di
  array
   – Ogni elemento dell'array dinamico è a sua volta un
     array
   – Le dimensioni degli array componenti devono
     essere specificate a tempo di scrittura del
     programma
• Esempio di puntatore ed allocazione matrice
  bidimensionale di n righe e 10 colonne:
     int (*p)[10] = new int[n][10] ;
• Deallocazione:
     delete [] p ;
Programmazione I - Paolo Valente, 2008/2009               48
Riepilogo
• Ingredienti fondamentali per la gestione degli
  array dinamici:
      – Operatore new
      – Operatore delete[]
      – Tipo di dato puntatore




Programmazione I - Paolo Valente, 2008/2009         49

More Related Content

What's hot

array of object pointer in c++
array of object pointer in c++array of object pointer in c++
array of object pointer in c++Arpita Patel
 
Pointers, virtual function and polymorphism
Pointers, virtual function and polymorphismPointers, virtual function and polymorphism
Pointers, virtual function and polymorphismlalithambiga kamaraj
 
[OOP - Lec 16,17] Objects as Function Parameter and ReturnType
[OOP - Lec 16,17] Objects as Function Parameter and ReturnType[OOP - Lec 16,17] Objects as Function Parameter and ReturnType
[OOP - Lec 16,17] Objects as Function Parameter and ReturnTypeMuhammad Hammad Waseem
 
Storage class in c
Storage class in cStorage class in c
Storage class in ckash95
 
File handling in C++
File handling in C++File handling in C++
File handling in C++Hitesh Kumar
 
Dynamic memory allocation
Dynamic memory allocationDynamic memory allocation
Dynamic memory allocationViji B
 
9. Input Output in java
9. Input Output in java9. Input Output in java
9. Input Output in javaNilesh Dalvi
 
Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with CatsMark Canlas
 
kexec / kdump implementation in Linux Kernel and Xen hypervisor
kexec / kdump implementation in Linux Kernel and Xen hypervisorkexec / kdump implementation in Linux Kernel and Xen hypervisor
kexec / kdump implementation in Linux Kernel and Xen hypervisorThe Linux Foundation
 
Puntatori e Riferimenti
Puntatori e RiferimentiPuntatori e Riferimenti
Puntatori e RiferimentiIlio Catallo
 
Introduction to the Kernel Chapter 2 Mrs.Sowmya Jyothi
Introduction to the Kernel  Chapter 2 Mrs.Sowmya JyothiIntroduction to the Kernel  Chapter 2 Mrs.Sowmya Jyothi
Introduction to the Kernel Chapter 2 Mrs.Sowmya JyothiSowmya Jyothi
 
Dictionary implementation using TRIE
Dictionary implementation using TRIEDictionary implementation using TRIE
Dictionary implementation using TRIECharmi Chokshi
 
Binary operator overloading
Binary operator overloadingBinary operator overloading
Binary operator overloadingBalajiGovindan5
 

What's hot (20)

array of object pointer in c++
array of object pointer in c++array of object pointer in c++
array of object pointer in c++
 
Pointers, virtual function and polymorphism
Pointers, virtual function and polymorphismPointers, virtual function and polymorphism
Pointers, virtual function and polymorphism
 
Structure c
Structure cStructure c
Structure c
 
[OOP - Lec 16,17] Objects as Function Parameter and ReturnType
[OOP - Lec 16,17] Objects as Function Parameter and ReturnType[OOP - Lec 16,17] Objects as Function Parameter and ReturnType
[OOP - Lec 16,17] Objects as Function Parameter and ReturnType
 
Storage class in c
Storage class in cStorage class in c
Storage class in c
 
File handling in C++
File handling in C++File handling in C++
File handling in C++
 
Dynamic memory allocation
Dynamic memory allocationDynamic memory allocation
Dynamic memory allocation
 
9. Input Output in java
9. Input Output in java9. Input Output in java
9. Input Output in java
 
Array
ArrayArray
Array
 
Functional Error Handling with Cats
Functional Error Handling with CatsFunctional Error Handling with Cats
Functional Error Handling with Cats
 
Pointer in C++
Pointer in C++Pointer in C++
Pointer in C++
 
Array
ArrayArray
Array
 
kexec / kdump implementation in Linux Kernel and Xen hypervisor
kexec / kdump implementation in Linux Kernel and Xen hypervisorkexec / kdump implementation in Linux Kernel and Xen hypervisor
kexec / kdump implementation in Linux Kernel and Xen hypervisor
 
Nested classes in java
Nested classes in javaNested classes in java
Nested classes in java
 
String in c
String in cString in c
String in c
 
Puntatori e Riferimenti
Puntatori e RiferimentiPuntatori e Riferimenti
Puntatori e Riferimenti
 
Introduction to the Kernel Chapter 2 Mrs.Sowmya Jyothi
Introduction to the Kernel  Chapter 2 Mrs.Sowmya JyothiIntroduction to the Kernel  Chapter 2 Mrs.Sowmya Jyothi
Introduction to the Kernel Chapter 2 Mrs.Sowmya Jyothi
 
Idiomatic kotlin
Idiomatic kotlinIdiomatic kotlin
Idiomatic kotlin
 
Dictionary implementation using TRIE
Dictionary implementation using TRIEDictionary implementation using TRIE
Dictionary implementation using TRIE
 
Binary operator overloading
Binary operator overloadingBinary operator overloading
Binary operator overloading
 

Viewers also liked

05 - Programmazione: Funzioni
05 - Programmazione: Funzioni05 - Programmazione: Funzioni
05 - Programmazione: FunzioniMajong DevJfu
 
13 Puntatori E Memoria Dinamica
13   Puntatori E Memoria Dinamica13   Puntatori E Memoria Dinamica
13 Puntatori E Memoria Dinamicaguest60e9511
 
07 - Programmazione: Tipi di base e conversioni
07 - Programmazione: Tipi di base e conversioni07 - Programmazione: Tipi di base e conversioni
07 - Programmazione: Tipi di base e conversioniMajong DevJfu
 
17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle liste17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle listeMajong DevJfu
 
Programmare Google Maps con Javascript
Programmare Google Maps con JavascriptProgrammare Google Maps con Javascript
Programmare Google Maps con Javascriptextrategy
 
Architettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di BaseArchitettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di BaseMajong DevJfu
 

Viewers also liked (8)

05 - Programmazione: Funzioni
05 - Programmazione: Funzioni05 - Programmazione: Funzioni
05 - Programmazione: Funzioni
 
13 Puntatori E Memoria Dinamica
13   Puntatori E Memoria Dinamica13   Puntatori E Memoria Dinamica
13 Puntatori E Memoria Dinamica
 
07 - Programmazione: Tipi di base e conversioni
07 - Programmazione: Tipi di base e conversioni07 - Programmazione: Tipi di base e conversioni
07 - Programmazione: Tipi di base e conversioni
 
17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle liste17 - Programmazione: Introduzione alle liste
17 - Programmazione: Introduzione alle liste
 
Corso c++
Corso c++Corso c++
Corso c++
 
Programmare Google Maps con Javascript
Programmare Google Maps con JavascriptProgrammare Google Maps con Javascript
Programmare Google Maps con Javascript
 
Architettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di BaseArchitettura dei Calcolatori 06 Elementi Architetturali Di Base
Architettura dei Calcolatori 06 Elementi Architetturali Di Base
 
Lezione1 Linguaggio C
Lezione1 Linguaggio CLezione1 Linguaggio C
Lezione1 Linguaggio C
 

Similar to 12 - Programmazione: Array dinamici e puntatori

10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturati10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturatiMajong DevJfu
 
15 - Programmazione: Algoritmi
15 - Programmazione: Algoritmi15 - Programmazione: Algoritmi
15 - Programmazione: AlgoritmiMajong DevJfu
 
11 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 211 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 2Majong DevJfu
 
06 1 array_stringhe_typedef
06 1 array_stringhe_typedef06 1 array_stringhe_typedef
06 1 array_stringhe_typedefPiero Fraternali
 
16 - Programmazione: Gestione memoria
16 - Programmazione: Gestione memoria16 - Programmazione: Gestione memoria
16 - Programmazione: Gestione memoriaMajong DevJfu
 
Linguaggio R, principi e concetti
Linguaggio R, principi e concettiLinguaggio R, principi e concetti
Linguaggio R, principi e concettiVincenzo De Maio
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScriptGiovanni Buffa
 
08 - Programmazione: Passaggio valori tra funzioni per riferimenti
08 - Programmazione: Passaggio valori tra funzioni per riferimenti08 - Programmazione: Passaggio valori tra funzioni per riferimenti
08 - Programmazione: Passaggio valori tra funzioni per riferimentiMajong DevJfu
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)STELITANO
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java BaseK-Tech Formazione
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...UltraUploader
 
Puntatori in C++
Puntatori in C++Puntatori in C++
Puntatori in C++marckmart
 
06 - Programmazione: Scope Variabili
06 - Programmazione: Scope Variabili06 - Programmazione: Scope Variabili
06 - Programmazione: Scope VariabiliMajong DevJfu
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)STELITANO
 
Sistemi Operativi: Il kernel linux - Lezione 06
Sistemi Operativi: Il kernel linux - Lezione 06Sistemi Operativi: Il kernel linux - Lezione 06
Sistemi Operativi: Il kernel linux - Lezione 06Majong DevJfu
 
13 - Programmazione: Compendio C - C++
13 - Programmazione: Compendio C - C++13 - Programmazione: Compendio C - C++
13 - Programmazione: Compendio C - C++Majong DevJfu
 

Similar to 12 - Programmazione: Array dinamici e puntatori (20)

10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturati10 - Programmazione: Tipi di dato strutturati
10 - Programmazione: Tipi di dato strutturati
 
15 - Programmazione: Algoritmi
15 - Programmazione: Algoritmi15 - Programmazione: Algoritmi
15 - Programmazione: Algoritmi
 
11 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 211 - Programmazione: Tipi di dato strutturati pt. 2
11 - Programmazione: Tipi di dato strutturati pt. 2
 
06 1 array_stringhe_typedef
06 1 array_stringhe_typedef06 1 array_stringhe_typedef
06 1 array_stringhe_typedef
 
16 - Programmazione: Gestione memoria
16 - Programmazione: Gestione memoria16 - Programmazione: Gestione memoria
16 - Programmazione: Gestione memoria
 
Linguaggio R, principi e concetti
Linguaggio R, principi e concettiLinguaggio R, principi e concetti
Linguaggio R, principi e concetti
 
Introduzione a JavaScript
Introduzione a JavaScriptIntroduzione a JavaScript
Introduzione a JavaScript
 
08 - Programmazione: Passaggio valori tra funzioni per riferimenti
08 - Programmazione: Passaggio valori tra funzioni per riferimenti08 - Programmazione: Passaggio valori tra funzioni per riferimenti
08 - Programmazione: Passaggio valori tra funzioni per riferimenti
 
Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)Lezione 16 (2 aprile 2012)
Lezione 16 (2 aprile 2012)
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Array
ArrayArray
Array
 
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...[Ebook   ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
[Ebook ita - security] introduzione alle tecniche di exploit - mori - ifoa ...
 
Puntatori in C++
Puntatori in C++Puntatori in C++
Puntatori in C++
 
ADT Stack
ADT StackADT Stack
ADT Stack
 
06 - Programmazione: Scope Variabili
06 - Programmazione: Scope Variabili06 - Programmazione: Scope Variabili
06 - Programmazione: Scope Variabili
 
Array in C++
Array in C++Array in C++
Array in C++
 
Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)Lezione 5 (7 marzo 2012)
Lezione 5 (7 marzo 2012)
 
Java Lezione 1
Java Lezione 1Java Lezione 1
Java Lezione 1
 
Sistemi Operativi: Il kernel linux - Lezione 06
Sistemi Operativi: Il kernel linux - Lezione 06Sistemi Operativi: Il kernel linux - Lezione 06
Sistemi Operativi: Il kernel linux - Lezione 06
 
13 - Programmazione: Compendio C - C++
13 - Programmazione: Compendio C - C++13 - Programmazione: Compendio C - C++
13 - Programmazione: Compendio C - C++
 

More from Majong DevJfu

9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA CloudMajong DevJfu
 
8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processesMajong DevJfu
 
7 - Architetture Software - Software product line
7 - Architetture Software - Software product line7 - Architetture Software - Software product line
7 - Architetture Software - Software product lineMajong DevJfu
 
6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformationMajong DevJfu
 
5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven ArchitectureMajong DevJfu
 
4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture PortfolioMajong DevJfu
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural stylesMajong DevJfu
 
2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture2 - Architetture Software - Software architecture
2 - Architetture Software - Software architectureMajong DevJfu
 
1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a productMajong DevJfu
 
10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural stylesMajong DevJfu
 

More from Majong DevJfu (20)

9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud9 - Architetture Software - SOA Cloud
9 - Architetture Software - SOA Cloud
 
8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes8 - Architetture Software - Architecture centric processes
8 - Architetture Software - Architecture centric processes
 
7 - Architetture Software - Software product line
7 - Architetture Software - Software product line7 - Architetture Software - Software product line
7 - Architetture Software - Software product line
 
6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation6 - Architetture Software - Model transformation
6 - Architetture Software - Model transformation
 
5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture5 - Architetture Software - Metamodelling and the Model Driven Architecture
5 - Architetture Software - Metamodelling and the Model Driven Architecture
 
4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio4 - Architetture Software - Architecture Portfolio
4 - Architetture Software - Architecture Portfolio
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles
 
2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture2 - Architetture Software - Software architecture
2 - Architetture Software - Software architecture
 
1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product1 - Architetture Software - Software as a product
1 - Architetture Software - Software as a product
 
10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles10 - Architetture Software - More architectural styles
10 - Architetture Software - More architectural styles
 
Uml3
Uml3Uml3
Uml3
 
Uml2
Uml2Uml2
Uml2
 
6
66
6
 
5
55
5
 
4 (uml basic)
4 (uml basic)4 (uml basic)
4 (uml basic)
 
3
33
3
 
2
22
2
 
1
11
1
 
Tmd template-sand
Tmd template-sandTmd template-sand
Tmd template-sand
 
26 standards
26 standards26 standards
26 standards
 

12 - Programmazione: Array dinamici e puntatori

  • 1. Array dinamici e puntatori
  • 2. Motivazioni • Gli oggetti considerati finora devono essere completamente definiti (tipo, nome e dimensione) a tempo di scrittura del programma • Ciò non costituisce un problema per gli oggetti di tipo primitivo, ma può essere limitativo per oggetti di tipo strutturato quali array e stringhe – talvolta non è possibile sapere a priori la quantità di dati da memorizzare/gestire • Per superare la rigidità della definizione statica delle dimensioni, occorre un modo per “allocare in memoria oggetti le cui dimensioni sono determinate durante l'esecuzione del programma” • Questo è possibile grazie al meccanismo di allocazione dinamica della memoria Programmazione I - Paolo Valente, 2008/2009 2
  • 3. Memoria libera • Prima dell'inizio dell'esecuzione di un processo, il sistema operativo riserva ad esso un spazio di memoria di dimensioni predefinite – quello che finora abbiamo chiamato memoria del programma – locazioni consecutive di memoria (tipicamente da 1 byte l'una) • Questo spazio di memoria è a sua volta organizzato in segmenti distinti • Uno di questi segmenti è chiamato – memoria libera, memoria dinamica oppure heap • E' possibile allocare oggetti all'interno della memoria dinamica in momenti arbitrari durante l'esecuzione del programma – ovviamente finché lo spazio non si esaurisce Programmazione I - Paolo Valente, 2008/2009 3
  • 4. Memoria libera Indirizzo prima locazione della memoria libera, ad es.: 0xFFFF0000 Memoria libera Indirizzo ultima locazione della memoria libera, mobile (come vedremo in seguito) Programmazione I - Paolo Valente, 2008/2009 4
  • 5. Allocazione dinamica • Gli oggetti allocati in memoria dinamica sono detti dinamici • In questa presentazione considereremo solo array dinamici – Array allocati in memoria dinamica durante l'esecuzione del programma – Come vedremo, il numero di elementi non è vincolato ad essere definito a tempo di scrittura del programma • Come si alloca un array dinamico? – Mediante l'operatore new • Come si accede ad un oggetto in memoria dinamica? – Come ogni altro oggetto è caratterizzato da un indirizzo nello spazio di memoria del processo – L'operatore new ritorna l'indirizzo dell'oggetto allocato in memoria dinamica Programmazione I - Paolo Valente, 2008/2009 5
  • 6. Operatore new • Vediamo l'uso dell'operatore new solo per allocare array new <nome_tipo> [<num_elementi>] ; – Alloca un array di <num_elementi> oggetti di tipo <nome_tipo>, non inizializzati (valori casuali) – <num_elementi> può essere un'espressione aritmetica qualsiasi • Ad esempio new int[10] ; // alloca un array dinamico // di 10 elementi • Ma possiamo anche scrivere int a ; cin>>a; new int[a] ; // alloca un array dinamico // di a elementi Programmazione I - Paolo Valente, 2008/2009 6
  • 7. Array dinamico allocato nello heap 0xFFFF0000 Indirizzo array in memoria, Memoria Array ad es.: libera dinamico 0xFFFF0008 Programmazione I - Paolo Valente, 2008/2009 7
  • 8. Valore di ritorno dell'operatore new • L'operatore new non ritorna un riferimento (nel senso di sinonimo) all'oggetto allocato • Gli oggetti dinamici sono oggetti senza nome • Come si fa per accedere a tali oggetti? – Come detto, l'operatore new ritorna l'indirizzo dell'oggetto allocato • Possiamo accedere all'oggetto tramite tale indirizzo • Ma dove lo memorizziamo? – Per memorizzare un indirizzo ci serve un oggetto di tipo puntatore Programmazione I - Paolo Valente, 2008/2009 8
  • 9. Tipi di dato Derivati Scalari, Fondamentali, Primitivi o Aritmetici Riferimenti Strutturati Puntatori array [] struct predefiniti enumerati enum bool char int float double Programmazione I - Paolo Valente, 2008/2009 9
  • 10. Puntatori • Un oggetto di tipo puntatore ha per valore un indirizzo di memoria • Le definizione di un oggetto puntatore ha la seguente forma [const] <tipo_oggetto_puntato> * [const] <identificat.> [ = <indirizzo>]; • Il primo qualificatore const è presente se si punta ad un oggetto non modificabile • Il secondo const è presente se il valore del puntatore, una volta inizializzato, non può più essere modificato • Per definire un puntatore inizializzato con l'indirizzo di un array dinamico di N elementi: int * p = new int [N] ; Programmazione I - Paolo Valente, 2008/2009 10
  • 11. Indirizzo array dinamico 0xFFFF0000 0xFFFF0008 p p è inizializzato con Array Memoria il valore ritornato da dinamico libera da new, ossia con l'indirizzo dell'array dinamico int * p = new int [N] ; Programmazione I - Paolo Valente, 2008/2009 11
  • 12. Accesso agli elementi • Accesso agli elementi di un array dinamico – Possibile in modo identico agli array statici – selezione con indice mediante parentesi quadre – gli indici partono da 0 Programmazione I - Paolo Valente, 2008/2009 12
  • 13. Proviamo ... • Scrivere un programma che – Allochi un array dinamico di interi, di dimensioni lette da stdin – Lo inizializzi – Lo stampi • Soluzione: parte dell'esempio seguente ... Programmazione I - Paolo Valente, 2008/2009 13
  • 14. Esempi di accesso agli elementi main() { int N ; cin>>N ; int * p = new int [N] ; for (int i = 0 ; i < N ; i++) p[i] = 0 ; // inizializzazione cout<<p[0]<<endl ; cin>>p[N] ; // Esempio di: ERRRORE LOGICO // E DI ACCESSO ALLA MEMORIA } Programmazione I - Paolo Valente, 2008/2009 14
  • 15. Valori, operazioni, tempo di vita • Un oggetto di tipo puntatore – Ha per valori un sottoinsieme dei numeri naturali o un puntatore che contenga 0 (NULL in C) viene detto puntatore nullo – Prevede operazioni correlate al tipo di oggetto a cui punta o A PARTE L'ASSEGNAMENTO, NON VEDREMO ALTRE OPERAZIONI CON I PUNTATORI – Segue le stesse regole di tempo di vita di un qualsiasi altro tipo di oggetto • I riferimenti ad un oggetto di tipo puntatore (compreso il riferimento di default, ossia il nome dell'oggetto) seguono le stesse regole di visibilità di tutti gli identificatori Programmazione I - Paolo Valente, 2008/2009 15
  • 16. Tempo di vita di un array dinamico • Torniamo agli array dinamici • NON CONFONDETE UN PUNTATORE CON L'ARRAY A CUI PUNTA !!! • Il puntatore serve solo a mettere da parte l'indirizzo dell'array per potervi poi accedere in un secondo momento • Una volta allocato, un array dinamico esiste fino alla fine del programma (o fino a che non viene deallocato, come stiamo per vedere) – Anche se non esistesse più il puntatore che contiene il suo indirizzo !!! Programmazione I - Paolo Valente, 2008/2009 16
  • 17. Puntatore ed array in memoria Memoria libera 0xFFFF0008 p Array Un puntatore e l'array a cui tale puntatore dinamico può puntare hanno tempi di vita indipendenti, ed occupano zone di memoria diverse. In particolare, se non deallocato, un array dinamico continua ad esistere anche se e quando il puntatore utilizzato per memorizzare il suo indirizzo non esiste più. Programmazione I - Paolo Valente, 2008/2009 17
  • 18. Deallocazione array dinamico • Si può deallocare esplicitamente un array dinamico, ossia liberare lo spazio da esso occupato nella memoria dinamica, mediante l'operatore delete[] <indirizzo_oggetto_da_deallocare> Programmazione I - Paolo Valente, 2008/2009 18
  • 19. Operatore delete [ ] • Prende per argomento l'indirizzo dell'array da deallocare Es.: int * p = new int[10] ; delete [] p ; // dealloca l'array dinamico // puntato da p • Può essere applicato solo all'indirizzo di un array dinamico allocato con l'operatore new – Altrimenti si ha un errore di gestione della memoria – Se si è fortunati, l'errore è segnalato durante l'esecuzione del programma • Può essere applicato anche al puntatore nullo, nel qual caso non fa nulla e non genera errori Programmazione I - Paolo Valente, 2008/2009 19
  • 20. Esempio main() { int vector[15]; // spazio per 15 interi int *dynVect; // spazio per il puntatore, non l'array ! int k ; cout<<quot;Inserire la dimensione desiderata del vettorenquot;; cin>>k ; dynVect = new int [k];   /* ora è possibile usare liberamente sia vector sia dynVect come array, lunghi 15 e k, rispettivamente */   for (int i=0;i<k;i++) dynVect[i] = i*i;   for (int i=0;i<15;i++) vector[i] = 2*i;   delete [] dynVect; // necessaria? } Programmazione I - Paolo Valente, 2008/2009 20
  • 22. Passaggio alle funzioni • Passaggio di un array dinamico ad una funzione – Possibile in modo identico agli array statici Oltre che o [const]<nome_tipo> identificatore [] il parametro formale può essere dichiarato [const]<nome_tipo> * identificatore – Le dimensioni dell'array passato come parametro attuale non sono implicitamente note alla funzione chiamata – Il passaggio dell'array è per riferimento – Usare il qualificatore const se si vuole evitare modifiche Programmazione I - Paolo Valente, 2008/2009 22
  • 23. Riferimenti e puntatori 1/2 • Ora possiamo dire cosa viene effettivamente passato ad una funzione che prende in ingresso un array, tanto statico quanto dinamico • Le viene passato l'indirizzo dell'array – O se vogliamo l'indirizzo del primo elemento dell'array • Quindi le definizioni [const]<nome_tipo> identificatore [] oppure [const]<nome_tipo> * identificatore sono di fatto definizioni di un parametro formale di tipo puntatore • All'atto della chiamata il parametro formale viene inizializzato con l'indirizzo dell'array Programmazione I - Paolo Valente, 2008/2009 23
  • 24. Riferimenti e puntatori 2/2 • A livello di linguaggio non si tratta quindi di un passaggio per riferimento, ma di un passaggio per valore – Il parametro formale contiene infatti una copia dell'indirizzo dell'array • Ma proprio siccome il parametro formale contiene (una copia de) l'indirizzo dell'array, allora tramite il parametro formale si accede esattamente all'array il cui indirizzo è passato come parametro attuale • Quindi ogni modifica effettuata all'array puntato dal parametro formale si riflette sull'array di cui si è passato l'indirizzo • Ecco perché a livello logico possiamo affermare che si tratta a tutti gli effetti di un passaggio per riferimento di un array Programmazione I - Paolo Valente, 2008/2009 24
  • 25. Ritorno da parte delle funzioni • Una funzione può ritornare l'indirizzo di un array dinamico • Il tipo di ritorno deve essere [const] <nome_tipo> * Programmazione I - Paolo Valente, 2008/2009 25
  • 26. Esercizio 1 (Specifica) • Scrivere un programma che utilizzi una funzione per leggere da input un certo numero di valori int e li inserisca in un array allocato dinamicamente dalla funzione stessa. La funzione deve restituire al main() il puntatore all'array dinamico creato. Stampare poi l'array nel main() Programmazione I - Paolo Valente, 2008/2009 26
  • 27. Esercizio 1 (Algoritmo della funzione) • E’ necessario chiedere in input il numero di valori che si vogliono inserire • Si alloca un array dinamico della dimensione richiesta • Si scandisce tutto il vettore, inserendo elemento per elemento Esercizio 1 (Rappresentazione informazioni) • Serve un puntatore a int sia nella funzione sia nel main() • Serve una variabile int per memorizzare la dimensione presa da input • Serve un int come indice per scandire l'array Programmazione I - Paolo Valente, 2008/2009 27
  • 28. Esercizio 1 (Programma) int* creaVett(void) { int num ; cout<<“Quanti valori? ”; cin>>num; int *v = new int[num] ; for (int i=0; i<num; i++) { cout<<”v[“<<i<<”]=”; cin>>v[i] ; } return v; Non si sa quanti elementi abbia } l'array. Il main() e altre eventuali funzioni non potrebbero utilizzare main() l'array senza sapere la dimensione. { Per poter usare l'array, il programma int *pv; va esteso ... pv = creaVett(); // come si fa // a stampare l'array? delete [] pv ; } Programmazione I - Paolo Valente, 2008/2009 28
  • 29. Esercizio 1 (Programma corretto) int* creaVett(int &num) { cout<<“Quanti valori? ”; cin>>num; int *v = new int[num] ; for (int i=0; i<num; i++) { cout<<”v[“<<i<<”]=”; cin>>v[i] ; } return v; } In questo modo, il main() può main() accedere propriamente { agli elementi dell'array int *pv, dim; pv = creaVett(dim); for (int i=0; i<dim; i++) cout<<pv[i]<<endl ; delete [] pv ; } Programmazione I - Paolo Valente, 2008/2009 29
  • 30. Esercizio 1 (Programma alternativo) void creaVett(int * &v, int &num) { cout<<“Quanti valori? ”; cin>>num; v = new int[num] ; for (int i=0; i<num; i++) { cout<<”v[“<<i<<”]=”; cin>>v[i] ; } } Versione (concettualmente più complessa) con due main() parametri che riportano sia { l'array sia la sua dimensione. int *pv, dim; La funzione deve restituire creaVett(pv, dim); l'array attraverso un parametro for (int i=0; i<dim; i++) passato per riferimento. Poiché il tipo dell'array è un puntatore cout<<pv[i]<<endl ; a int (cioè, int *), il tipo del delete [] pv ; parametro è un riferimento a } puntatore a int Programmazione I - Paolo Valente, 2008/2009 30
  • 31. Riferimento a puntatore • Tipo derivato • Il tipo di partenza è un puntatore • Definizione [const]<nome_tipo> * & <identificatore> ; Programmazione I - Paolo Valente, 2008/2009 31
  • 32. Esercizio 2 • Scrivere una funzione vett_copy(...) che prenda in ingresso un array di interi, ne crei un altro uguale, e ritorni (l'indirizzo del) secondo array mediante un parametro di uscita (un parametro quindi di tipo riferimento a puntatore) Programmazione I - Paolo Valente, 2008/2009 32
  • 33. Esercizio 2 void vett_copy(const int* v1, int num, int*& pv2) { pv2 = new int[num] ; for (int i=0; i<num; i++) pv2[i] = v1[i]; } main() { int vettore[] = {20,10,40,50,30}; int* newVet = 0 ; vett_copy(vettore, 5, newVet); delete [] newVet ; } Programmazione I - Paolo Valente, 2008/2009 33
  • 34. Esempio puntatore ad array costante main() { int N ; cin>>N ; int * p = new int [N] ; int * q = p ; // q punta allo stesso array const int * r = q ; // r punta allo stesso array, // ma tramite r non lo si potrà // modificare cin>>q[0] ; // corretto cin>>r[0] ; // errore segnalato a tempo di // compilazione: non si può utilizzare // r per cambiare valore all'array } Programmazione I - Paolo Valente, 2008/2009 34
  • 35. Esempio puntatore costante main() { int N ; cin>>N ; int *p ; p = new int [N] ; int * const s = p ; // s punta allo stesso array // e non potrà cambiare valore p = new int [N] ; // d'ora in poi p punta ad un // diverso array, l'unico // riferimento al precedente è // rimasto s s = p ; // ERRORE: s non può cambiare valore } Programmazione I - Paolo Valente, 2008/2009 35
  • 36. Riassunto qualificatore const • Un puntatore ad array dinamico costante non può essere utilizzato per modificare il valore degli elementi dell'array • Una variabile di tipo puntatore può essere (ri)assegnata in ogni momento – Una costante di tipo puntatore invece può essere solo inizializzata – Questo può evitare gli errori pericolosi che vedremo tra qualche slide Programmazione I - Paolo Valente, 2008/2009 36
  • 37. Flessibilità e problemi seri • Una variabile di tipo puntatore è come una variabile di un qualsiasi altro tipo • Quindi può essere utilizzata anche se non inizializzata !!!! – Errore logico e di accesso/gestione della memoria • Inoltre può essere (ri)assegnata in ogni momento • Infine più di un puntatore può puntare allo stesso oggetto – Quindi possono esservi effetti collaterali • Ma anche di peggio ... Programmazione I - Paolo Valente, 2008/2009 37
  • 38. Problema serio: dangling reference • Dangling reference (pending pointer) – Si ha quanto un puntatore punta ad una locazione di memoria in cui non è presente alcun oggetto allocato – Tipicamente accade perché il puntatore non è stato inizializzato, o perché l'oggetto è stato deallocato Programmazione I - Paolo Valente, 2008/2009 38
  • 39. Puntatore non inizializzato main() { int N ; cin>>N ; int *p ; // p contiene un valore casuale cin>>p[0] ; // ERRORE LOGICO E DI GESTIONE DELLA // MEMORIA: p non è stato // inizializzato/assegnato // all'indirizzo di alcun array // dinamico } Programmazione I - Paolo Valente, 2008/2009 39
  • 40. Oggetto deallocato main() { int N ; cin>>N ; int * p = new int [N] ; delete [] p ; cout<<p[0]<<endl ; // ERRRORE LOGICO // E DI ACCESSO ALLA MEMORIA } Programmazione I - Paolo Valente, 2008/2009 40
  • 41. Per ridurre i problemi • Ovunque possibile, utilizzare perlomeno puntatori costanti Es: int dim ; cin>dim ; int * const p = new int[dim] ; • Così siamo costretti ad inizializzarli e non possiamo riassegnarli ad altri array o magari a puntatori pendenti Programmazione I - Paolo Valente, 2008/2009 41
  • 42. Esaurimento memoria • In assenza di memoria libera disponibile, l'operatore new fallisce – viene generata una eccezione – se non gestita, viene stampato un messaggio di errore ed il programma termina • Se si vuole, si può – gestire l'eccezione oppure – “agganciare” il fallimento dell'operatore ad una propria funzione o Tale funzione verrà invocata in caso di fallimento • Non vedremo nessuna delle due soluzioni, quindi i nostri programmi semplicemente termineranno in caso di esaurimento della memoria Programmazione I - Paolo Valente, 2008/2009 42
  • 43. Problema serio: memory leak • Esaurimento inaspettato della memoria causato da mancata deallocazione di oggetti non più utilizzati – Spesso correlato con la perdita di riferimenti all'oggetto stesso Programmazione I - Paolo Valente, 2008/2009 43
  • 44. Esempio di memory leak void fun() { int N ; cin>>N ; int * p = new int [N] ; } main() { fun() ; // nel main p non è visibile, ma una volta invocata // fun(), l'array rimane in memoria; inoltre, una // volta terminata fun() si è perso ogni // riferimento all'array, quindi, tra l'altro, non // si può più deallocarlo ! ... } Programmazione I - Paolo Valente, 2008/2009 44
  • 45. Stringhe dinamiche • E’ possibile allocare array dinamici di oggetti di qualsiasi tipo – Come si alloca una stringa dinamica? – Come si alloca una array di struct? Programmazione I - Paolo Valente, 2008/2009 45
  • 46. Allocazione stringa dinamica • Stringa di 10 caratteri: char * const str = new char[11] ; • Stringa di dimensione definita da stdin: int dim ; cin>>dim ; char * const str = new char[dim+1]; Programmazione I - Paolo Valente, 2008/2009 46
  • 47. Allocazione di array di struct struct persona { char nome_cognome[41]; char codice_fiscale[17]; float stipendio; }; persona * const t = new persona[10] ; Programmazione I - Paolo Valente, 2008/2009 47
  • 48. Matrici dinamiche • Una matrice è un array di array • Quindi una matrice dinamica è un array dinamico di array – Ogni elemento dell'array dinamico è a sua volta un array – Le dimensioni degli array componenti devono essere specificate a tempo di scrittura del programma • Esempio di puntatore ed allocazione matrice bidimensionale di n righe e 10 colonne: int (*p)[10] = new int[n][10] ; • Deallocazione: delete [] p ; Programmazione I - Paolo Valente, 2008/2009 48
  • 49. Riepilogo • Ingredienti fondamentali per la gestione degli array dinamici: – Operatore new – Operatore delete[] – Tipo di dato puntatore Programmazione I - Paolo Valente, 2008/2009 49