2016-10-06 1 views
0

Also habe ich diesen Code in c geschrieben, der einfache doppelt verknüpfte Listenaufgaben wie die Liste erstellt, einen Knoten nach/vor einem gegebenen aktuellen NODE einfügt , entfernt einen gegebenen aktuellen Knoten und so weiter, aber ich stieß auf dieses Problem, als ich versuchte, die Liste zu zerstören. Was passiert ist, wenn ich die Liste zerstöre, hebt sie alle Knoten richtig auf (zumindest denke ich das, was ich in der Debugger-Uhr sehe), aber wenn ich überprüfe, ob der Kopf- und Endzeiger auf NULL seit den Knoten nein zeigen es existiert länger, der Kopf zeigt auf NULL, aber mein Schwanz zeigt immer noch auf etwas, von dem ich nicht sicher bin, ob es ein Knoten von der Liste ist, der nicht richtig freigegeben wurde oder etwas anderes.Warum zeigt mein Schwanz immer noch auf Etwas, anstatt auf NULL zu zeigen, nachdem ich die Liste zerstört habe

Kann mir jemand sagen, was passiert? Hier ist der relevante Code;

Dies ist die Funktion, die alle Knoten freigibt, so dass die Liste

void DListDestruct(DList* list) { 
DListNode* tempHead = list->head;; 

while (tempHead != NULL) { 
    tempHead = tempHead->next; 
    free(list->head); 
    list->head = tempHead; 
} 

if (list->tail == NULL) { 
    list->size = 0; 
} 


} 


    //Creation of the structs for the list  

typedef struct DListNode_struct { 
    char *str; 
    int blankIndex; 
    int blankLength; 
    struct DListNode_struct *next; 
    struct DListNode_struct *prev; 
} DListNode; 

typedef struct DList_struct { 
    int size; 
    DListNode *head; 
    DListNode *tail; 
} DList; 



/* This creates a new list and initializes the head/tail */ 

void DListConstruct(DList* list) { 

    list->head = NULL; 
    list->tail = NULL; 
    list->size = 0; 

} 


/* inserts newNode after the given currNode */ 

void DListInsertAfter(DList* list, DListNode* currNode, DListNode* newNode) { 

DListNode* sucNode = NULL; 

if (list->head == NULL) { 
    list->head = newNode; 
    list->tail = newNode; 
    list->size = list->size++; 
} 

else if (currNode == list->tail) { 
    list->tail->next = newNode; 
    newNode->prev = list->tail; 
    list->tail = newNode; 
    list->size = list->size++; 
} 

else { 
    sucNode = currNode->next; 
    newNode->next = sucNode; 
    newNode->prev = currNode; 
    currNode->next = newNode; 
    sucNode->prev = newNode; 
    list->size = list->size++; 
} 
} 


/* inserts newNode before the given currNode */ 
void DListInsertBefore(DList* list, DListNode* currNode, DListNode* newNode) { 
DListNode* predNode; 


if (list->head == NULL) { 
    list->head = newNode; 
    list->tail = newNode; 
    list->size = list->size++; 
} 

else if (currNode->prev != NULL) { 
    predNode = currNode->prev; 
    newNode->next = currNode; 
    newNode->prev = predNode; 
    currNode->prev = newNode; 
    predNode->next = newNode; 
    list->size = list->size++; 
} 

else if (currNode->prev == NULL) { 
    newNode->next = currNode; 
    currNode->prev = newNode; 
    list->head = newNode; 
    list->size = list->size++; 
} 

} 

So wieder zu zerstören, warum es ist, dass, wenn ich die Liste zerstören, die DListDestroy Funktion (auf die erste) verwenden, werden alle Knoten werden freigegeben, der Head-Zeiger zeigt auf NULL, aber der Tail-Zeiger zeigt immer noch auf etwas?

Vielen Dank im Voraus!

+0

'Liste-> Größe = Liste-> Größe ++;' -> undefiniertes Verhalten. Verwenden Sie einfach 'list-> size ++;' – chux

+0

Ist es nicht Ihre Aufgabe, Tail auf NULL zu setzen? Wo machst du das in 'DListDestruct()'? Anstelle von 'if (list-> tail == NULL) { Liste-> size = 0; } 'was Sie brauchen, ist' list-> tail = NULL; Liste-> Größe = 0; '. –

+0

Ich bin nur ein Anfänger in C, also dachte ich, dass nachdem ich alle Knoten den richtigen Weg freigegeben habe, sowohl der Kopf- als auch der Endzeiger auf NULL zeigen sollten, da die Knoten bereits freigegeben wurden. Ist das nicht der Punkt, auf den der Kopf- und Schwanzzeiger zeigen sollte, wenn ich alle Knoten lösche? – einacio

Antwort

0

Das liegt daran, dass das Schwanzstil auf die Adresse des Knotens zeigt, den Sie freigegeben haben, also zeigt es jetzt auf etwas Müll.

Der Kopf zeigt auf wo auch immer "tempHead" zeigt und am Ende der Schleife zeigt es auf Null, weil Sie während des Einfügens Null in den nächsten des letzten Knotens setzen.

Abschließend zeigt der Schwanz auf die Adresse des letzten Knotens, der Müll ist. Der Kopf zeigt auf den nächsten Knoten, der NULL ist.

+0

okay es macht Sinn was du gesagt hast. Aber ich brauche meinen Schwanz, um auf NULL zu zeigen, nachdem ich alle Knoten freigegeben habe und nicht an die Adresse des Knotens, den ich freigegeben habe. Also gibt es eine Möglichkeit, die Liste zu zerstören und meinen Schwanz auf NULL zu zeigen, wenn alle Knoten freigegeben sind? – einacio

+1

Fügen Sie diese Zeile hinzu, nachdem Sie alle Knoten "list-> tail = NULL freigegeben haben;' – ViewSource

+0

@einacio tail hält NULL, wenn Sie NULL setzen, sonst nicht. So einfach ist das. – immibis

Verwandte Themen