Newsgroup: it.comp.lang.c++
Titolo: distruggere array di classi

Salve a tutti,
 ho una classe MyClass di cui, all'interno di un mio programma, posso
gestirne al massimo otto istanze.
Allora, inizialmente dichiaro :
MyClass* S[8]; 
MyClass* Act; // quella attiva di volta in volta
// ed inizializzo (poiche' il VC non pone a NULL automaticamente)
S[0]=NULL; S[1]=NULL; S[2]=NULL; S[3]=NULL;
S[4]=NULL; S[5]=NULL; S[6]=NULL; S[7]=NULL;
Act=NULL;
Naturalmente prima avevo definito NULL=0;
Durante il programma, se si decide ad esempio di usare il quinto
elemento dell'array faccio:
 if(S[4]==NULL)  // se e' scelto per la prima volta
  { S[4]=new MyClass(); } 
Act=S[4];
ecc.... (e lavoro tranquillamente su Act)
e lo stesso per gli altri.
E fin qui tutto va liscio (almeno cosi' pare). Insomma posso lavorare
senza problemi sulle istanze definite spostandomi da una all'altra
tranquillamente (ogni volta Act punta all'istanza scelta).
Alla fine del programma pero' vorrei rilasciare la memoria
eventualmente occupata. E qui la mia ignoranza domina:
Se faccio:
 if(S[0]!=NULL) delete S[0];
 if(S[1]!=NULL) delete S[1];
 if(S[2]!=NULL) delete S[2];
 if(S[3]!=NULL) delete S[3];
 if(S[4]!=NULL) delete S[4];
 if(S[5]!=NULL) delete S[5];
 if(S[6]!=NULL) delete S[6];
 if(S[7]!=NULL) delete S[7];
succede un casino (e si pianta windows).
Se invece faccio solo (indipendentemente dal fatto che sia stato
allocato o meno):
delete (S[0]); // o comunque delete S[i] con i generico da 0 a 7
tutto va tranquillo (almeno apparentemente).
Se non mi preoccupo proprio di rilasciare la memoria lo stesso va
tutto liscio (ma non credo che la memoria resti libera).
Conclusione:
Qualcuno mi spiega gli array di classi ?
Grazie.

 tutto liscio (ma non credo che la memoria resti libera).
all'uscita del processo viene liberata tutta la memoria occupata dal processo,
anche se non l'hai liberata con delete (o free()) (almeno sotto win, non so su
altre piattaforme).
cmq ti ripeto che il problema è altrove.
ho provato questo programma con VC++6 su win2000
(le varie pause le ho messe solo per controllare l'utilizzo della memoria dal
task manager)
che esegue tutte le operazioni che hai detto tu (e che ho 'sistemato' io...),
e tutto va bene:
#include <iostream>
class MyClass
{
private:
 char *megabyte;
public:
 MyClass() { megabyte = new char[1024*1024]; }
 ~MyClass() { delete[] megabyte; }
 void foo() { std::cout << "MyClass::foo" << std::endl; }
};
MyClass *S[8] = { 0 }; // inizializza tutti gli elementi a 0
MyClass *Act = 0; // inizializza Act a 0
using namespace std;
void pause()
{
 cout << ":: Enter per continuare...";
 cin.get();
}
int main()
{
 pause();
 // alloca la memoria
 Act = S[4] = new MyClass;
 Act->foo();
 pause();
 // libera la memoria
 for(int k=0; k<8; k++)
 {
  if(S[k])
   delete S[k];
 }
 pause();
 return 0;
}
--
ciao
xaero

   delete S[k];
Questo test e' inutile. Fare delete di un puntatore nullo e'
come non fare nulla: basta quindi scrivere "delete S[k];".
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

ho provato questo programma con VC++6 su win2000
Sei stato gentilissimo.
Grazie ancora.

 Questa non la sapevo.
si, ma non č un motivo per smettere di usare delete o free().
se all'interno di un programma (es in un ciclo o in risposta all'input
dell'utente) devi istanziare classi con new, e non liberi la memoria quando
l'oggetto non serve piů, lasciando correre il programma puoi notare che piano
piano le prestazioni del sistema iniziano a calare, win inizia a swappare...
:D
--
ciao
xaero

sicuro che era qua il problema?
Credo di si perche' ora va tutto bene. Spiego meglio:
tra i dati della classe MyClass e' definito un array allocabile
dinamicamente; pero' quest'array non e' allocato automaticamente
quando istanzio un oggetto MyClass. Cioe' puo' capitare che creo un
oggetto di classe MYClass senza che in esso venga allocato spazio per
l'array (in altre parole, l'array viene allocato solo in particolari
condizioni di funzionamento dell'oggetto).
Pero' io avevo messo nel distruttore della classe Myclass
l'istruzione:
delete (points);
come se l'array points fosse sempre allocato.
Spero di essere stato abbastanza chiaro.
Grazie.
Ciao.

 Credo di si perche' ora va tutto bene. Spiego meglio:
Come ti è stato detto, applicare delete a un puntatore nullo è
perfettamente legale e non produce alcun tipo di problema. Pertanto,
quella verifica prima del delete è _assolutamente_ inutile. In altre
parole, se c'era un problema, non era quella la causa.
Piuttosto, se (come dici sotto) è possibile che l'array non venga
allocato, assicurati che il puntatore venga *espressamente* inizializzato
a zero nel costruttore di MyClass, giacchè tale inizializzazione non
avviene automaticamente.
Max


 if (points!=NULL) delete (points);
delete NULL;   non fa niente, quindi il programma dovrebbe avere
lo stesso comportamento sia con l'if che senza.
	Mauro

 potrebbe tornare utile in certi casi)
questa *č* un'istigazione alla cattiva programmazione; meglio non farci 
troppo affidamento; se proprio non vuoi incasinarti con i puntatori puoi 
usare qualche forma di Smart Pointer.
Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 usare qualche forma di Smart Pointer.
NON è istigazione alla cattiva programmazione.
io non ho detto puoi evitare di chiamare delete se sei vicino alla fine del
programma...
io ho detto soltanto quello che è verità, e cioè che all'uscita del processo
anche la memoria non deallocata con delete viene liberata ugualmente; ma ho
spiegato anche per quale motivo BISOGNA continuare ad usare delete.
ciao
xaero

 anche la memoria non deallocata con delete viene liberata ugualmente
La TUA verita'.  Sull'Amiga non era deallocata affatto, ad esempio...
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it
Q: Why do programmers always mix up Christmas and Halloween?
A: Because 25 Dec = 31 Oct

 altre piattaforme).
--
ciao
xaero

anche la memoria non deallocata con delete viene liberata ugualmente;
E se un processo (ad esempio un servizio o demone) non esce mai? Non
sai i problemi di memoria che si vengono a creare...
Luc.

 usare delete.
non su tutti i sistemi operativi, come ti ha fatto notare anche Maurizio. 
Anche il DOS non la deallocava; e fare affidamento su questa "verità" rende 
il programma non portabile.
ciao Anto


avviene automaticamente.
Si. Infatti era proprio li che nasceva il guaio.
Grazie.