5

Strutture dati semplici, ad esempio elenchi collegati, in cui il puntatore "successivo" è un puntatore intelligente. Quando il nodo principale viene eliminato, il puntatore intelligente per 'successivo' entra in gioco e esegue un'eliminazione ricorsiva. Per una lunga lista, questo rapidamente salta la pila.Il puntatore intelligente salta la pila a causa della cancellazione ricorsiva

Ho dovuto tornare indietro per sostituire questi puntatori intelligenti con semplici puntatori grezzi. Mi sto perdendo qualcosa qui?

+0

'soffia la pila'? puoi elaborare per favore. – Flexo

+2

Quasi sicuramente non è colpa del puntatore intelligente. Mostraci un codice, ci sarà un bug nell'implementazione. In ogni caso, l'eliminazione dell'elenco completo dovrebbe avvenire per iterazione, non per ricorsione, quindi dovrebbe richiedere uno spazio di stack costante. –

+1

@Kerrek: presumibilmente, il distruttore del puntatore intelligente cancella il pointee, che darà una ricorsione se il pointee contiene un altro puntatore intelligente. Non vedo come potrebbe essere implementato il puntatore intelligente per evitarlo. –

risposta

5

Supponendo che ho capito il tasto destro ed entrambi head e next sono puntatori intelligenti si può evitare questo facendo:

head = head->next; 

o equivalente. La tua testa "vecchia" verrà eliminata e il vecchio elemento del secondo posto verrà promosso in testa. Tutto in un unico cambiamento coerente, senza ricorsione profonda. L'unica pre-condizione a questo è che la testa non è NULL per cominciare.

Come Mike ha indicato nel commento se l'obiettivo è quello di eliminare l'intera lista, è possibile ripeterlo all'interno di un ciclo.

+3

Sì, quindi è possibile cancellare l'intero elenco non in modo ricorsivo con 'while (head) head = head-> next;' –

+1

Non dimenticare di commentarlo, perché qualcuno andrà e verrà WTF :) – UncleBens

+0

"Your" old 'la testa verrà cancellata e il vecchio oggetto del secondo posto verrà promosso alla testa. "- Questa affermazione, pur riflettendo su ciò che sta accadendo, è un'incredibile semplificazione. A meno che il lettore casuale sia * molto * esperto in entrambe le funzionalità di linguaggio e di puntatore intelligente, questa soluzione, mentre funziona, è più magica di ogni altra cosa. E se sono così familiari, probabilmente non ne hanno bisogno in primo luogo. Un passo per passo su esattamente ciò che sta accadendo durante quel semplice compito 'head = head-> next' renderà * sostanzialmente * più chiaro. – WhozCraig

2

I puntatori intelligenti all'interno di una classe di elenchi collegati non sembrano comprarti molto. I puntatori grezzi mi sembrano perfettamente ragionevoli. Penso che i puntatori intelligenti siano utilizzati al meglio per situazioni meno controllate in cui sarebbe facile dimenticare di cancellare qualcosa.

Attenzione, devi essere stato un elenco enorme per far saltare in aria lo stack, sei sicuro di non aver riscontrato un errore nel codice?

+0

I puntatori intelligenti negli interni acquistano maggiori garanzie di sicurezza. Gratuito in termini di manodopera e pochissimo costo di stoccaggio costante aggiuntivo. Solo questo sembra valere la pena per me. – Flexo

+0

Sì, è un punto giusto. – john

+0

Bene, io uso un puntatore intelligente per tenere un nodo appena creato prima che venga allegato alla lista. Ma una volta collegato, è la responsabilità del distruttore del nodo della lista. Come avete notato voi, devo comunque eseguire l'elaborazione manuale nel distruttore per sostituire la ricorsione automatica dei puntatori intelligenti con l'iterazione codificata a mano. Potresti per favore approfondire i problemi di sicurezza delle eccezioni. Ho pensato che qualsiasi eccezione non gestita in un distruttore ucciderà comunque il programma, indipendentemente dai puntatori intelligenti. – Jay