Visualizzazione dei risultati da 1 a 3 su 3
  1. #1

    [c++] Vita variabili in funzione ricorsiva con inserimento in contenitore STL

    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.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    obj son;

    è una variabile locale alla funzione, allocata sullo stack, che viene distrutta automaticamente quando la funzione termina.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Si, ovvio.

    Allora per il primo caso, colpa mia. Come sospettavo non c'è memory leak: basta sostituire con:

    codice:
    int main()
    {
        {
    	obj root;
    	recursive(root);
    
        }
    	return 0;
    }
    Per il secondo caso (ricorsione con depth > 1) rimane il problema che ho spiegato, rimane quindi da capire se è possibile memorizzare il puntatore al padre senza utilizzare allocazione dinamica e relativa lista di puntatori, benché ne dubiti.
    Fracty - The Fractal Generator



    If you cannot choose a concise name that expresses what the method does, it is possible that your method is attempting to perform too many diverse tasks.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.