Newsgroup: it.comp.lang.c++
Titolo: triplo puntatore

Ciao a tutti, sto facendo delle prove sui puntatori e vorrei dichiarare un 
triplo puntatore a struttura.
Con un puntatore non ho problemi, con due nemmeno, ma col terzo il programma 
va in crash: Su windows non ricevo nessun messaggio, compilando su Linux (in 
entrambi i caso utilizzo g++) ricevo come messaggio "segmentation fault", 
che se non sbaglio significa errore di segmentazione della memoria (quindi 
violazione di accesso, giusto?) Potete spiegarmi perchč? Grazie a tutti.
#include<iostream>
using namespace std;
 typedef struct punto
 {
  int a;
  int b;
 };
main()
{
 punto *x;
 x=new(punto);
 x->a=10;
 cout<<"\n\n"<<x->a;
 punto **y;
 y=new(punto*);
 (**y).a=20;
 cout<<"\n\n"<<(**y).a;
 punto ***z;
 //z=new(punto**);
 /*perche' non funziona con triplo puntatore?!!
 (***z).a=5;
 (***z).b=20;*/
 cin.get();
 /*cout<<"\n\nvalore di a: "<<(***z).a;
 cout<<"\n\nvalore di b:"<<(***z).b;*/
}

  cout<<"\n\n"<<(**y).a;
Ti premetto che ho sonno e potrei dire una castroneria, ma 
nel frammento qui sopra tu dichiari un puntatore a 
puntatore ma non lo fai puntare alla struttura. Forse 
poteva andare qualcosa del genere (l'ho modificato solo in 
un punto c-like ma dovrebbe farsi anche più sotto). Sono 
sicuro di star dicendo una sciocchezza ma credo che il 
problema sia nell'assegnazione della variabile puntatore 
lungo la catena di puntatori che vai creando. Qualcuno mi 
corigerà (cit.) :)
ciao!
Apx.
#include<iostream>
using namespace std;
  typedef struct punto
  {
   int a;
   int b;
  };
main()
{
  punto *x;
  x=new(punto);
  x->a=10;
  cout<<"\n\n"<<x->a;
  punto **y;
  y=new(punto*);
/* --------------------- QUI
(*y) = x ;
-----------------  */


 (non solo col triplo) ma per puro caso non si inkioda.
in effetti mi chiedevo perché non si inchiodasse anche col
primo...

primo...
Sarà uno di quei comportamente non definiti che capitano col C++
Infatti cosi funziona:
struct punto {
       int a;
       int b;
};
int main() {
    punto* x = new (punto);
    x->a = 10;
    x->b = 10;
    cout << x->a << " " << x->b << endl;
    punto** y = new (punto*);
    *y = x;
    (*y)->a = 20;
    (*y)->b = 20;
    cout << (*y)->a << " " << (*y)->b << endl;
    punto*** z = new (punto**);
    *z = y;
    (**z)->a = 30;
    (**z)->b = 30;
    cout << (**z)->a << " " << (**z)->b << endl;
}
Solo che in questo modo x, y e z puntano alla stessa struttura. Se vuoi 
dichiarare 3 puntatori indipendenti puoi fare cosi:
int main() {
    punto* x = new (punto);
    x->a = 10;
    x->b = 10;
    punto** y = new (punto*);
    *y = new (punto);
    (*y)->a = 20;
    (*y)->b = 20;
    punto*** z = new (punto**);
    *z = new (punto*);
    **z = new (punto);
    (**z)->a = 30;
    (**z)->b = 30;
    cout << x->a << " " << x->b << endl;
    cout << (*y)->a << " " << (*y)->b << endl;
    cout << (**z)->a << " " << (**z)->b << endl;
}
allocando memoria per tutti i puntatori, dal più "esterno" al più "interno"
Però mi chiedevo se ci fosse un modo per evitare quell'assegnazione 
esplicita e inglobare tutto nella fase di definizione del puntatore a 
puntatore... forse usando qualche cast? 


con *y=x sto passando al puntatore al tipo punto *y l'indirizzo contenuto 
nella variabile x, che č quello dell'area di memoria puntata? Se uso (**y).a 
accedo ai campi della struttura? Ho un sacco di confusione in testa, a 
questo punto non capisco piů cosa succede quando utilizzo la new. Potresti 
darmi qualche chiarimento in piů? Sono alle prime armi col C++ e i 
puntatori. Grazie mille. 

 Marco 

 succede quando utilizzo la new.
La new restituisce un puntatore all'oggetto che alloca. Nel tuo caso:
punto* x = new (punto);
new restituisce un punto*  (puntatore a punto)
Saluti 

 l'indirizzo del primo puntatore al secondo?
Cosa intendi con primo e secondo puntatore?
Quello che hai scritto tu, ovvero:
punto pippo; // Creando l'oggetto pippo ne allochi anche la memoria
punto *z = &pippo; // Prendi l'indirizzo di pippo e lo assegni a z.
con new diventerebbe:
punto* z = new (punto) // Crei l'oggetto allocando la memoria e assegni 
l'indirizzo a z, tutto in un unica istruzione senza la necessità di usare 
pippo.
Ciao 

 darmi qualche chiarimento in più?
Considera il seguente pseudocodice generico:
  T* p = new T
Se T è 'int', allora 'p' sarà un 'int*' e '*p' sarà un 'int'.
Analogamente, se T è 'int*', 'p' sarà 'int**' e '*p' sarà 'int*'.
In questo caso, per assegnare un valore a '*p' dovrai disporre di un valore
di tipo 'int*', ossia l'indirizzo di un 'int'.
Se vuoi usare solo 'new', per rendere -diciamo- "usabile" una variabile di
tipo int**, dovrai prima istanziare un 'int*':
  int* * p = new int*; 
poi assegnare un valore a '*p', istanziando un 'int':
  *p = new int;
Volendo potresti anche fare tutto in un colpo solo:
  int* * p = new int* ( new int ); 
Nota che, per rilasciare le risorse usate, ad *OGNI* chiamata a 'new', dovrà
corrispondere una (e una sola!) chiamata a 'delete'. Quindi:
  delete *p;
  delete p;
Se invochi solo "delete p", perdi irrimediabilmente la possibilità di
rilasciare la memoria allocata dalla seconda 'new'.
Max

  int* * p = new int* ( new int );
Nel caso di int*** che istruzioni si dovrebbe usare?
Questa (che ho ipotizzato ad intuito) non funziona:
int*** p = new int* (new int* (new int));
Ciao 



int*** p = new int** (new int* (new int));
Dr. Atlantis

 int*** p = new int** (new int* (new int));
Vero, ci vuole un altro asterisco :-) 

Scusatemi, forse sono un po' citrullo, ma non capisco bene cosa cambia 
usando questo:
#include<iostream>
using namespace std;
 typedef struct punto
 {
  int a;
  int b;
 };
main()
{
 punto *x=new(punto);
 cout<<"\n\nX ha indirizzo "<<&x;
 cout<<"\n\ne contiene l'indirizzo dell'area di memoria puntata, che e': 
"<<x;
 x->a=10;
 x->b=20;
 cout<<"\n\nraggiungo i membri 'a' e 'b' della struttura puntata";
 cout<<"\n\ne gli assegno valore "<<x->a<<"e "<<x->b;
 punto **y=&x;
 /*punto **y=new(punto*);
 *y=x;*/
 cout<<"\n\n\n\nY ha indirizzo "<<&y;
 cout<<"\n\ne contiene l'indirizzo del puntatore X che e': "<<y;
 (*y)->a=30;
 (*y)->b=40;
 cout<<"\n\nraggiungo i membri 'a' e 'b' della struttura puntata";
 cout<<"\n\ne gli assegno valore "<<(*y)->a<<" e "<<(*y)->b;
 punto ***z=&y;
 /*punto ***z=new(punto**);
 *z=y;*/
 cout<<"\n\n\n\nZ ha indirizzo "<<&z;
 cout<<"\n\ne contiene l'indirizzo del puntatore Y che e': "<<z;
 (**z)->a=50;
 (**z)->b=60;
 cout<<"\n\nraggiungo i membri 'a' e 'b' della struttura puntata";
 cout<<"\n\ne gli assegno valore "<<(**z)->a<<" e "<<(**z)->b;
 cout<<"\n\n\n\ntutti i puntatori accedono accedere alla stessa struttura 
punto, infatti:";
 cout<<"\n\nse utilizzo X leggo che a vale: "<<x->a<<" e b vale: "<<x->b;
 cout<<"\n\nse utilizzo Y leggo che a vale: "<<(*y)->a<<" e b vale: 
"<<(*y)->b;
 cout<<"\n\nse utilizzo Z leggo che a vale: "<<(**z)->a<<" e b vale: 
"<<(**z)->b;
 cin.get();
}
e questo:
#include<iostream>
using namespace std;
 typedef struct punto
 {
  int a;
  int b;
 };
main()
{
 punto *x=new(punto);
 cout<<"\n\nX ha indirizzo "<<&x;
 cout<<"\n\ne contiene l'indirizzo dell'area di memoria puntata, che e': 
"<<x;
 x->a=10;
 x->b=20;
 cout<<"\n\nraggiungo i membri 'a' e 'b' della struttura puntata";
 cout<<"\n\ne gli assegno valore "<<x->a<<"e "<<x->b;
 punto **y=new(punto*);
 *y=x;
 cout<<"\n\n\n\nY ha indirizzo "<<&y;
 cout<<"\n\n*Y ha indirizzo "<<&*y;
 cout<<"\n\n**Y ha indirizzo "<<&**y;
 cout<<"\n\nY contiene l'indirizzo del puntatore *Y che e': "<<y;
 cout<<"\n\nall'interno di *Y e' contenuto l'indirizzo dell'area puntata: 
"<<cout<<*y;
 (*y)->a=30;
 (*y)->b=40;
 cout<<"\n\nraggiungo i membri 'a' e 'b' della struttura puntata";
 cout<<"\n\ne gli assegno valore "<<(*y)->a<<" e "<<(*y)->b;
 punto ***z=new(punto**);
 *z=y;
 cout<<"\n\n\n\nZ ha indirizzo "<<&z;
 cout<<"\n\n*Z ha indirizzo "<<&*z;
 cout<<"\n\n**Z ha indirizzo "<<&**z;
 cout<<"\n\nZ contiene l'indirizzo del puntatore **Z che e': "<<z;
 cout<<"\n\nall'interno di *Z e' contenuto l'indirizzo dell'area puntata: 
"<<cout<<*z;
 (**z)->a=50;
 (**z)->b=60;
 cout<<"\n\nraggiungo i membri 'a' e 'b' della struttura puntata";
 cout<<"\n\ne gli assegno valore "<<(**z)->a<<" e "<<(**z)->b;
 cout<<"\n\n\n\ntutti i puntatori accedono accedere alla stessa struttura 
punto, infatti:";
 cout<<"\n\nse utilizzo X leggo che a vale: "<<x->a<<" e b vale: "<<x->b;
 cout<<"\n\nse utilizzo Y leggo che a vale: "<<(*y)->a<<" e b vale: 
"<<(*y)->b;
 cout<<"\n\nse utilizzo Z leggo che a vale: "<<(**z)->a<<" e b vale: 
"<<(**z)->b;
 cin.get();
}
col secondo alla fine quanti puntatori ho creato?! Perchè visualizzando *y e 
*z oltre all'indirizzo della struttura punto ho una parte di indirizzo 
(prima) che non capisco a cosa faccia riferimento?
Grazie a chiunque mi risponda, inizio ad essere un po' in crisi!

 usando questo:
Invia solo il codice su cui hai dubbi, non tutto quello che comprende il 
programma, se no si fa confusione inutilmente.
Quali sono le due righe di codice da confrontare?
*y = x
e
**y = &x
???
Se si, nel primo caso *y è un puntatore alla struttura e quindi puoi 
assegnargli x. Nel secondo caso, **y è un puntatore a puntatore alla 
struttra, e puoi quindi assegnargli l'indirizzo di un puntatore alla 
struttura. 

 assegnargli x. Nel secondo caso, **y č un puntatore a puntatore alla 


 *y=x;
Qui allochi uno spazio di memoria a cui punta y. In tale spazio 
successivamente inserisci x tramite l'assegnazione.
In pratica, se y deve puntare a x, non è necessario che prima allochi spazio 
con new e poi gli assegni x, puoi direttamente assegnare l'indirizzo di x 
come hai fatto nel cas precedente.
Ciao