Newsgroup: it.comp.lang.c++
Titolo: allocazione dinamica matrice

Sono alle prese con il problema della allocazione dinamica di una matrice,
mantenendo però la notazione a doppio indice  (M[i][j] per intenderci).
Leggendo le faq ho appreso che la cosa si risolve  facendo:
int dim1=... ;
int dim2=... ;
int **M=new int* [dim1];
for (int i=0; i<dim1; ++i)
  M[i]=new int[dim2];
E questo metodo l'ho capito.
Il docente del corso di programmazione 1 ha però suggerito di fare
semplicemente:
int (*M)[dim2]=new int[dim1][dim2];
Le 2 dichiarazioni sono in realtà la stessa cosa e la seconda è un modo di
scrivere più compattamente la prima?
Non riesco propio a capire la 2° dichiarazione. Che significa? Me lo potete spiegare?
Ringrazione anticipatamente,
Alessandro Bergamo
---------
email: 
el_co...@libero.it
icq: 132581870
---------

 modo di scrivere più compattamente la prima? 
No. La prima dichiara un puntatore a un puntatore a int, che viene usato
per accedere a un array di puntatori a int allocato con new. La seconda
dichiara un puntatore a un array di int, che viene usato per accedere ad
un array di array di int (allocato con new). (Nota che nel secondo caso,
dim2 *deve* essere una costante.)
Se la riscrivi introducendo un typedef, la seconda probabilmente ti
apparirà più chiara:
  typedef int int_dim2_t [ dim2 ];
      // int_dim2_t è un alias per "array di int con dimens. dim2"
  int_dim2_t * M = new int_dim2_t [ dim1 ];
Max

 dim2 *deve* essere una costante.)
Grazie mille per la risposta, ora ho capito.
Ma se dim2 deve essere una costante perchè facendo
cin >> dim2;
cin >> dim1;
e poi dichiarando la matrice, g++ non protesta?
E anche a runtime tutto sembra andare ok.


 e poi dichiarando la matrice, g++ non protesta?
Perché gcc permette di istanziare un array sullo stack le cui dimensioni
siano stabilite in fase di esecuzione.
Si tratta di una possibilità non prevista nel C++ Standard.
Lo Standard C del '99 introduce questa caratteristica, e non è escluso che
un giorno venga incorporata anche nel C++, ma attualmente il comportamento
del gcc è da considerarsi un'estensione dello Standard. Dovrebbe esistere
un'opzione da riga di comando per inibirla.
Max

 Non riesco propio a capire la 2° dichiarazione. Che significa? Me lo potete spiegare?
Dunque: entrambe dichiarano un puntatore. Il primo puntatore M però
punta ad uno o più (quindi in generale ad un array allocato
dinamicamente) puntatori ad intero. Ognuno di questi poi punta ad uno o
più (anche in questo caso array allocati dinamicamente) interi. Quindi
il risultato è una serie di array di interi di lunghezza potenzialmente
diversa ai quali si accede con due indirezioni (da M si accede
all'i-esimo puntatore e da questo all'array da esso puntato).
Il secondo puntatore M invece punta ad uno o più array di interi. Quindi
qui hai una serie di array di interi disposti sequenzialmente (gli array
del caso precedente invece non sono in generale sequenziali) che devono
quindi necessariamente essere della stessa lunghezza (altrimenti
l'aritmetica del puntatore non potrebbe funzionare). A questi array si
accede con l'unica indirezione del puntatore M.
Proviamo con un disegno (da leggere con un font a passo fisso).
Caso 1:
M -> P1 P2 P3 P4
      |  |  |  |
     i1 i1 i1 i1
     i2 i2 i2
        i3 i3
        i4
Caso 2:
M -> i1 i2 i3 i4 i5  i1 i2 i3 i4 i5  i1 i2 i3 i4 i5
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

 E anche a runtime tutto sembra andare ok.
Forse è un'estensione del g++? Mi pare che in C ora questa possibilità
faccia parte dello standard.


 mantenendo però la notazione a doppio indice  (M[i][j] per intenderci).
non è che per caso frequenti il primo anno di ing. informatica a napoli???
;-))
ciao!

 non è che per caso frequenti il primo anno di ing. informatica a
napoli???
A padova. mi spiace :)

Grazie mille ad entrambi per le risposte.
Siete stati molto esaurienti.
--------
email: 
el_co...@libero.it
icq: 132581870
--------