Newsgroup: it.comp.lang.c++
Titolo: Delete matrice

Come di fa a deallocare una matrice creata nel seguente modo?
int row = 2;
int (*matr)[5] = new int[row][5];
Io ho provato a utilizzare l'espressione per gli array
delete[] matr;
che viene compilata senza errori. E' corretta?
Grazie.
Marco



Non ho provato di persona, ma penso che dovrebbe funzionare. Il motivo
principale dell'esistenza di delete[] e' per gli array di oggetti, per cui
non e' sufficiente la deallocazione della memoria ma anche la chiamata dei
costruttori per ciascun elemento. Cosa che ovviamente non avviene per tipi
primitivi come int.
Davide Marcato.
----------------------------------------------------
| -- Freelance International Consultant
| -- Win32/MFC/COM Development & Training
| -- Technical Writer & Speaker
----------------------------------------------------
| -- Email: 
mar...@programmers.net
| -- Web: 
http://www.DavideMarcato.com
----------------------------------------------------

che viene compilata senza errori. E' corretta?
Scusami se rispondo in ritardo, ma mi era sfuggito...
Immagino che matr sia dichiarata nel modo
int** matr;
e che poi tu esegua *matr = new int* [row];
e quindi con un for tu completi la cosa.
In questo caso nella deallocazione devi operare in modo
inverso, ovvero fare un for del tipo
for(int i=0; i<row; ++i)
  delete[] matr[i];
e quindi fare una
delete[] matr;
Questo e` l'unico modo corretto e standard!
utilizzare semplicemente
delete[] matr;
e` a norma di standard "undefined behaviour".
Il fatto che con alcuni compilatori funzioni non significa
che sia corretto, in teoria il tuo compilatore potrebbe
generare il classico "codice per formattare il disco"
e la colpa sarebbe unicamente tua!
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

primitivi come int.
Questo non e` del tutto vero...
Se il tuo gestore dello heap usasse pool distinti per singoli oggetti
ed array ti ristroveresti con un bel bug anche con i tipi primitivi.


Paolo
Ho provato a creare due matrici nel modo seguente:
int main() {
 int row = 2;
 int (*matr)[5] = new int[row][5];
 for(int i = 0; i < row; i++)
  delete[] matr[i];                               <= Warning C4154
 delete[] matr;
 int** matr2;
 matr2 = new int*[row];
 for(i = 0; i < row; i++)
  matr2[i] = new int[5];
 for(i = 0; i < row; i++)
  delete[] matr2[i];
 delete[] matr2;
 return 0;
}
Per matr2 tutto OK.
Quando compila invece la parte relativa a "matr" viene visualizzato il
seguente warning:
warning C4154: deletion of an array expression; conversion to pointer
supplied
Come mai applicando lo stesso metodo alle due matrici si ottiene solo in un
caso tale segnalazione?



ed array ti ristroveresti con un bel bug anche con i tipi primitivi.
Certamente, ma quando avviene realmente questo? Siamo d'accordo che a
rigore la forma delete[] usata in quel modo non e' corretta, ma penso che
di fatto funzioni ovunque, almeno per tipi primitivi.


caso tale segnalazione?
Non stai applicando lo stesso metodo...
matr2 viene sicuramente utilizzata in modo corretto, matr invece mi pare
venga utilizzata scorrettamente.
Infatti matr e` dichiarata come puntatore a 5 interi, solo che la inizializzi
utilizzando un puntatore ad array di interi (primo errore).
Quando esegui delete[] matr[i] stai cercando di dealllocare un array,
ma matr[i] e` un intero e non un puntatore ad array (secondo errore).
Il tuo compilatore non segnala errori nell'inizializzazione di matr, ma
capisce che c'e` qualcosa che non va nella delete in questione,
il mio invece non fornisce neanche quella warning!


di fatto funzioni ovunque, almeno per tipi primitivi.
Non e` un buon motivo per fare le cose in modo non standard...
Non sei d'accordo?
E poi un domani potresti decidere di utilizzare un gestore dello
heap diverso, avendo scritto correttamente il programma potresti farlo
senza dover toccare il vecchio codice!


Non sei d'accordo?
Assolutamente si'. Pensavo la domanda fosse del tipo "funzionerebbe...",
non "e' cosa buona a giusta..." :-)


utilizzando un puntatore ad array di interi (primo errore).
La dichiarazione della matrice in questo modo inconsueto l'ho trovata nel
testo C++ Primer 3rd Ed.  di S. Lippman(pag 414) il problema era appunto che
poi non spiega come si possa deallocare, o meglio indica l'utilizzo
dell'espressione delete[] senza specificare il comportamento per array
multidimensionali. E' possibile che ci sia un errore di stampa?

multidimensionali. E' possibile che ci sia un errore di stampa?
Non saprei...
Volendo fare una cosa simile con array multidimensionali,
dovresti scrivere
int main() {
  int* matr[5];
  for(int i=0; i<5; ++i)
    matr[i] = new int[10];
  matr[0][0] = 5;  // esempio d'uso
  for(int i=0; i<5; ++i)
    delete[] matr[i];
}
ma come vedi non c'e` un'unica delete[].
In effetti il metodo e` identico a quello in cui si usa un int**
con la differenza che una delle dimensioni della matrice e`
gia` fissata a compile-time.
