Ho una classe di questo tipo:
codice:
class obj
{
public:
obj()
: parent(NULL),
depth(0)
{ }
obj* parent;
list<obj> children;
int depth;
};
Dove voglio mettere in evidenza che la lista dei figli contiene degli oggetti memorizzati come valori e non dei puntatori.
Ho una funzione ricorsiva, che voglio utilizzare per riempire la mia struttura dati:
codice:
void recursive(obj& parent)
{
// Imposta la profondità di uscita a scopo di esempio
if(parent.depth == 1)
return;
// Crea un figlio
obj son;
son.parent = &parent;
son.depth = parent.depth + 1;
// Ricorre sul figlio
recursive(son);
// Inserisce son come figlio dell'argomento
parent.children.push_back(son);
}
E che utilizzo ad esempio cosi:
codice:
int main()
{
obj root;
recursive(root);
return 0;
}
Il problema sta nel fatto che ho un memory leak.
Vediamo di capire dov'è il problema:
depth = 0)
Quando entro per la prima volta nella funzione ricorsiva creo il primo ed unico figlio di root (ogni oggetto avrà sempre un unico figlio per com'è scritta la funzione). A questo figlio assegno come padre l'indirizzo di root, quindi anche concluso il metodo ricorsivo il puntatore è valido, e come profondità 1.
depth = 1)
Entro per la seconda volta nella funzione ricorsiva, testo che la condizione parent.depth == 1 è vera quindi ritorno. Immediatamente dopo viene assegnato il figlio con depth = 1 alla radice, inserendolo nella lista root.children.
A questo punto a che cosa è dovuto il memory leak?
Inizialmente avevo creato l'esempio perché volevo poter mantenere la lista dei figli come lista di valori (e non come lista di puntatori) e sapevo che ci sarebbero stati problemi quando arrivavo ad un livello di ricorsione pari a 2. Infatti (correggetemi se sbaglio), se la condizione fosse stata invece:
codice:
if(parent.depth == 2)
return;
depth = 0)
Come caso precedente.
depth = 1)
Dopo che il test non è passato creo il figlio del figlio di root (root->son->son) e gli assegno come puntatore al padre un valore che non sarà più valido una volta usciti completamente del metodo ricorsivo, poiché l'indirizzo che sto assegnando appartiene ad una variabile il cui scopo è delimitato all'interno della stessa funzione ricorsiva. Quindi la mia struttura dati non sarebbe stata valida.
Per concludere:
Dove sbaglio?
A cosa è dovuto il memory leak?
Come posso creare una lista di valori e non di puntatori?
Grazie.