Een LinkedList-destructor schrijven?

Is dit een geldige LinkedList-destructor? Ik ben nog steeds een beetje in de war door hen.

Ik wil er zeker van zijn dat ik dit goed begrijp.

LinkedList::~LinkedList()
 {
   ListNode *ptr;
   for (ptr = head; head; ptr = head)
   {
     head = head->next
     delete ptr;
   }
}

Dus aan het begin van de lus wordt de pointer ptr ingesteld om het adres van head te bevatten, het eerste knooppunt in de lijst. head wordt dan ingesteld op het volgende item, dat het begin van de lijst wordt zodra deze eerste verwijdering plaatsvindt. ptr wordt verwijderd, evenals het eerste knooppunt. Bij de eerste iteratie van de lus wordt de aanwijzer weer op kop gezet.

Waar ik me zorgen over maak, is het bereiken van het allerlaatste knooppunt. De toestand “hoofd;” moet controleren of het niet null is, maar ik weet niet zeker of het zal werken.

Alle hulp wordt op prijs gesteld.


Antwoord 1, autoriteit 100%

Waarom zou je het niet veel eenvoudiger doen – met een elegante while-loop in plaats van zorgvuldig te proberen te analyseren of die overgecompileerde for-loop correct is?

ListNode* current = head;
while( current != 0 ) {
    ListNode* next = current->next;
    delete current;
    current = next;
}
head = 0;

Antwoord 2, autoriteit 26%

Je kunt het door een debugger halen of je kunt het door dat stukje wetware in je schedel halen – beide zullen je laten zien dat het goed werkt. Laten we bijvoorbeeld beginnen met de lijst:

head(47) -> [47]single_node -> [NULL]end-of-list.

Die lijst door uw verklaringen laten lopen:

  • ptr = headstelt ptrin op 47.
  • headis niet nul, dus voer een lus in.
  • head = head->nextstelt headin op NULL.
  • delete ptrverwijdert de single_node.
  • ptr = headstelt ptrin op NULL.
  • headis nu NULL (0), dus verlaat de lus.

Zo, je hebt het enige item in de lijst verwijderd en headis nu ingesteld op NULL. Dat is alles wat u hoeft te doen.

Je kunt iets soortgelijks doen met een langere lijst of een lege lijst, je zult merken dat het nog steeds in orde is (er is geen echt verschil tussen een lijst met één element en een lijst met vijftig elementen).

Terzijde, ik ben geen grote fan van het behandelen van pointers als booleans – ik schrijf het liever als iets als:

for (ptr = head; head != NULL; ptr = head)

Het maakt de code naar mijn mening beter leesbaar en je offert niet echt prestatie op (tenzij je een hersendode compiler hebt). Maar dat is een kwestie van smaak.

Her je reactie:

Waar ik me zorgen over maak, is het bereiken van het allerlaatste knooppunt. De toestand “hoofd;” moet controleren of het niet null is, maar ik weet niet zeker of het zal werken.

Het zal werken. Een waarde van nul wordt als onwaar behandeld, dus u zult merken dat u head->next nooit derefereert wanneer head NULL is, simpelweg omdat u de lus-body voor dat punt hebt verlaten (of zelfs niet de body bent binnengegaan als de lijst is leeg).

Elke andere aanwijzerwaarde wordt als waar behandeld en u gaat de lustekst in of vervolgt deze.


Antwoord 3, autoriteit 16%

De voorwaarde “hoofd;” moet controleren of het niet null is, maar ik weet niet zeker of het zal werken.

Ja, “head” is op zichzelf hetzelfde als “head != null” — maar waarom zou u een zinloze sneltoets gebruiken als u het zelfs verwarrend vindt? Het zijn nog maar 6 toetsaanslagen (en genereert identieke machinecode), dus ga voor de lange vorm.

Bovendien is uw code iets ingewikkelder dan nodig, omdat u een for()-constructie gebruikt. Waarom gebruik je geen while()? Je code zal veel schoner zijn.

Ten slotte realiseer ik me dat je dit als een leeroefening doet, maar onthoud die lijst<> bevindt zich in de standaardbibliotheek — Gelinkte lijsten zijn officieel een “Opgelost probleem”.


Antwoord 4, autoriteit 11%

OK getest

Destructor voor klassenlijst

List::~List()
{
    Node *n = this->front, *current = NULL; //initialization part
    while(n)                               //start cleanup of nodes of the list
    {
        current = n;
        n=n->next;
        delete(current);
    }
    front = end = NULL;
}

Antwoord 5

Uw code kan correct zijn, probeer deze uit te voeren met b.v. valgrind en kijk wat er staat. Ik zou het echter zo schrijven:

for (ListNode *current = head, *next; current; current = next) {
    next = current->next;
    free(current);
}

Antwoord 6

Dit is een betere benadering voor het vrijmaken/verwijderen van het geheugen met behulp van destructor van een Linked-List.

List()::~List()
            {
                for( Link* ptr= Head; Head; Head= Head->next)
                {
                    delete ptr;
                }
            }

Other episodes