Pagina 1 di 1
[programmazione] Allocazione e pulizia della memoria in C++
Inviato: gio 6 set 2007, 10:13
da Bart
Ciao,
ho creato questo ciclo in C++:
Codice: Seleziona tutto
for(int j=0;j<the_set3->size();j++){
esempio[j]=the_set3->get_example(j);
for(int i=0;i<dimPCA;i++){
vett_a(i)=esempio[j].example[i].att;
}
VecSet_a.Add(vett_a);
}
dove esempio è allocato così:
e svm_example è:
Codice: Seleziona tutto
typedef struct svm_example{
SVMINT length;
svm_attrib* example;
SVMFLOAT y;
SVMFLOAT alpha;
} SVM_EXAMPLE;
Ora io vorrei sapere come usare delete per cancellare tutta la memoria allocata per esempio e esempio[j]->example
. Praticamente la domanda è: "Date le strutture sopra indicate, per deallocare la memoria allocata con esempio e esempio->example come dovrei usare delete?" Al momento non ho definito distruttori e quindi se faccio: "delete esempio" cancello solamento la memoria allocata per esempio[0] e non per ogni esempio[j]->example. Se faccio "delete []esempio" ottengo degli errori in fase di esecuzione.
Spero di essere stato il più chiaro possibile. Grazie. 
Re: [programmazione] Allocazione e pulizia della memoria in
Inviato: gio 6 set 2007, 11:44
da Simone_R
Bart ha scritto:
}[/code]
dove esempio è allocato così:
e svm_example è:
Codice: Seleziona tutto
class svm_example{
public:
svm_example() { example = 0 ;}
~svm_example(){ if (example != 0) delete [] example ; } // distruttore
SVMINT length;
svm_attrib* example;
SVMFLOAT y;
SVMFLOAT alpha;
} SVM_EXAMPLE;
Non usare le strutture ma usa le classi.
Definisci una funzione membro distruttore ~svm_example() che verrà automaticamente chiamata quando chiami il delete su un oggetto di tipo svm_example o quando la funzione termina.
E anche un costruttore svm_example() che inizializza il campo example come vuoto (Uguale a zero).
Forse funziona anche con le struct (Ma non ricordo .... )
Verifica la sintassi (Ho scritto a memoria

)
Ciao.
Inviato: gio 6 set 2007, 11:49
da lamarozzo
Da quel che vedo mi sembra che ci sia un errore.
esempio viene allocato semplicemente come un puntatore
a svm_example e non come array. L'allocazione dovrebbe essere così
Codice: Seleziona tutto
svm_example *esempio=new svm_example[the_set3->size()]
Per questo quando fai delete[] esempio ti dà errore.
Dal tuo codice non sembra però che esempio ti serva come
un vero e proprio array, forse potresti usarlo semplicemente
come puntatore semplice
Codice: Seleziona tutto
for(int j=0;j<the_set3->size();j++){
esempio=the_set3->get_example(j);
for(int i=0;i<dimPCA;i++){
vett_a(i)=esempio.example[i].att;
}
VecSet_a.Add(vett_a);
}
dipende dall'utilizzo che ne fai dopo.
Per quanto riguarda la deallocazione devi andare invece in ordine inverso.
Cioè prima deallochi gli example e poi esempio.
Codice: Seleziona tutto
for (j=0;j<;j++)
{
delete [] esempio[j].example;
}
delete[] esempio;
Per fugare ogni dubbio ti consiglio inoltre di usare Valgrind, che
è anche pacchettizzato su slacky. E' un programma che ti aiuta
a scovare tutti i memory leak in un programma.
Inviato: gio 6 set 2007, 12:56
da Bart
Grazie per le risposte, siete stati chiarissimi. Ho un altro dubbio. Visto che ogni tanto nel programma ottengo errori di accesso ad aree di memoria sto cercando di vagliare tutte le possibili cause. Il mio dubbio: è se creo degli oggetti in questa maniera
, dove CNFloatVectorSet è una classe con tanto di distruttore, devo poi lanciare un delete vecSet_a o non è necessario?
Inviato: gio 6 set 2007, 13:02
da lamarozzo
L'operatore delete va usato "solo" quando l'oggetto è stato creato
dall'operatore new. Nel tuo caso l'oggetto verrà distrutto automaticamente
non appena uscirà di scope. A presto

Inviato: gio 6 set 2007, 13:16
da simplex
Quoto lamarozzo e come ti ha consigliato Simoe_R, usa le classi, sono molto piu' gestibili dele strutture, e anche il main() diventa piu' fico

Inviato: gio 6 set 2007, 14:02
da Bart
lamarozzo ha scritto:Per fugare ogni dubbio ti consiglio inoltre di usare Valgrind, che
è anche pacchettizzato su slacky. E' un programma che ti aiuta
a scovare tutti i memory leak in un programma.
Purtroppo sto usando visual c++ su XP e quindi il programma in questione non va bene. Ne conosci altri per caso?
Inviato: gio 6 set 2007, 15:05
da lamarozzo
purtroppo (o per fortuna, dipende dai punti di vista) non sono
pratico di ambiente microsoft. Sicuramente però Visual Studio
(come ogni buon ambiente di sviluppo)
includerà qualche debugger per la memoria, prova a spulciare la
documentazione. In bocca al lupo

Inviato: gio 6 set 2007, 16:31
da Simone_R
Bart ha scritto:Grazie per le risposte, siete stati chiarissimi. Ho un altro dubbio. Visto che ogni tanto nel programma ottengo errori di accesso ad aree di memoria sto cercando di vagliare tutte le possibili cause. Il mio dubbio: è se creo degli oggetti in questa maniera
, dove CNFloatVectorSet è una classe con tanto di distruttore, devo poi lanciare un delete vecSet_a o non è necessario?
Non è necessario (se l'oggetto è statico):
Il distruttore viene, in ogni caso, chiamato in modo automatico al termine della funzione che contiene l'oggetto.
Attento se all'interno della tua classe (come descritta sopra) allocchi un oggetto dinamico questo non verrà distrutto in modo automatico se non definisci un distruttore che lo fa esplicitamente.
Il distruttore automatico chiama in modo automatico e ricorsivo SOLO i distruttori dei campi statici.
Codice: Seleziona tutto
class pincopallino {
MyClass *dyn ; // campo dinamico
MyClass bho ; // campo statico
}
int fun() {
pincopallino xxx ;
xxx.dyn = new MyClass() ;
......
return 1;
// xxx.dyn NON viene distrutto
}
Inviato: gio 6 set 2007, 16:43
da Bart
Ok SImone_R, però se io ho una classe PincoPallino, che alloca memoria al suo interno con un new e creo un distruttore che cancella appositamente tutto ciò che viene allocato (sempre con new), se creo un oggetto statico (pincoPallino oggetto)non serve comunque che chiami il distruttore, vero? In teoria il distruttore viene chiamato quando termina lo scope e si libererà anche la memoria allocata con new dal costruttore della classe. Comunque penso di aver risolto un po' di memory leaks, grazie veramente a tutti.

Inviato: gio 6 set 2007, 17:08
da Simone_R
Bart ha scritto:Ok SImone_R, però se io ho una classe PincoPallino, che alloca memoria al suo interno con un new e creo un distruttore che cancella appositamente tutto ciò che viene allocato (sempre con new), se creo un oggetto statico (pincoPallino oggetto)non serve comunque che chiami il distruttore, vero?
Giusto
Bart ha scritto:
In teoria il distruttore viene chiamato quando termina lo scope e si libererà anche la memoria allocata con new dal costruttore della classe. Comunque penso di aver risolto un po' di memory leaks, grazie veramente a tutti.

Non in teoria ma in pratica ...... (in new vanno distrutti esplicitamente ... nel distruttore ... )
Inviato: gio 6 set 2007, 19:07
da Bart
Scusatemi, un'ultima domanda sempre sul tema. Se io ho un oggetto pluto della classe PincoPallino
e faccio un "delete pluto", nel caso in cui dovessi riutilizzare pluto, magari per inserirgli nuovi dati, devo ridichiararlo? Cioè devo fare
oppure
?
Inviato: gio 6 set 2007, 22:59
da lamarozzo
E' giusta la prima soluzione, nel secondo caso
il compilatore dà errore perchè ci sarebbero due variabili con lo stesso nome all'interno dello scope.
Comunque, non è una pratica molto comune.
