2016-05-24 4 views
1

Ich versuche, über C++ zu lernen, und ich habe Probleme mit der Speicherverwaltung und das Konzept der Destruktoren. Ich habe versucht, eine Warteschlangenimplementierung zu schreiben, die Verknüpfte Listen verwendet, und ich empfange "Aborted (Core Dumped)" Fehlermeldung, wenn ich versuche, meine verknüpften List-Knoten in meiner Destruktor-Methode (fett) zu löschen. Wenn jemand weiß, was ich falsch mache, lass es mich wissen!C++ LinkedList Queue Implementierung und Destruktor Fehler: "Aborted (Core Dumped)"

Hier ist der Code für mein Destruktormethode:

template <class T> 
Queue<T>::~Queue(){ 
    Node<T> *currHead = head; 
    while(currHead != NULL){ 
    Node<T> *nextHead = currHead->next; 
    delete currHead; 
    currHead = nextHead; 
    } 
    Node<T> *currTail = tail; 
    while(currTail != NULL){ 
    Node<T> *nextTail = currTail->next; 
    delete currTail; 
    currTail = nextTail; 
    } 
} 

Und für meine volle LinkedList Warteschlange Implementierung ist hier Bezug:

template <class T> 
class Node{ 
public: 
    T data; 
    Node<T> *next=NULL; 
}; 

template <class T> 
class Queue{ 
public: 
    Queue(); 
    ~Queue(); 
    void push(T); 
    T pop(); 
    int size=0; 
    Node<T> *head=NULL; 
    Node<T> *tail=NULL; 
}; 

template <class T> 
Queue<T>::Queue(){} 

template <class T> 
Queue<T>::~Queue(){ 
    Node<T> *currHead = head; 
    while(currHead != NULL){ 
    Node<T> *nextHead = currHead->next; 
    delete currHead; 
    currHead = nextHead; 
    } 
    Node<T> *currTail = tail; 
    while(currTail != NULL){ 
    Node<T> *nextTail = currTail->next; 
    delete currTail; 
    currTail = nextTail; 
    } 
} 

template <class T> 
void Queue<T>::push(T data){ 
    Node<T> *node = new Node<T>; 
    node->data = data; 
    if(head == NULL){ 
    head = node; 
    }else{ 
    tail->next = node; 
    } 
    tail = node; 
    size++; 
} 

template <class T> 
T Queue<T>::pop(){ 
    if(size == 0){ 
    throw "Empty Queue"; 
    }else{ 
    Node<T> *oldHead = head; 
    T oldData = oldHead->data; 
    head = head->next; 
    size--; 
    delete oldHead; 
    return oldData; 
    } 
} 

EDIT:

ich auch die folgende Definition versucht haben, für den Destruktor aber bekomme ich den gleichen Fehler:

template <class T> 
Queue<T>::~Queue(){ 

    while(head != NULL){ 
    Node<T> *currHead = head; 
    head = head->next; 
    delete currHead; 
    } 

    while(tail != NULL){ 
    Node<T> *currTail = tail; 
    tail = tail->next; 
    delete currTail; 
    } 
} 
+0

'currHead = nextHead;' nach 'löschen currHead;'? Sie tun ähnliche Sachen viele Male in Ihrem Code. –

+0

Was soll ich tun? Ich bin hier ratlos - Wenn Sie meine EDIT sehen, habe ich etwas anderes für den Destruktor versucht, aber ich bekomme immer noch den "Aborted (Core Dumped)" Fehler – mathmonkey

+0

nicht nur in Ihrem Destruktor, auch in Ihrer * full Linkedlist Queue-Implementierung * Sie machen einen ähnlichen Fehler. –

Antwort

3

Im ersten Teil Ihres Destruktors löschen Sie alle Listenelemente beginnend mit head. Im zweiten Teil des Destruktors versuchen Sie, das letzte Listenelement wieder zu löschen, indem Sie den Zeiger im Tail verwenden, aber es ist bereits im ersten Teil gelöscht.

+0

Das ist was ich dachte, aber ich überprüfte - auch nach dem Löschen Kopf im ersten Teil des Destruktors, immer noch Schwanz! = NULL, also sollte ich nicht noch danach löschen müssen? – mathmonkey

+0

@mathmonkey Die Head- und Tail-Zeiger speichern die gleiche Adresse, also wird 'tail! = NULL' auch dann wahr, wenn der Speicher bereits gelöscht ist. – Rakete1111

+0

Das scheint das Problem zu sein, ist es aber nicht. Wenn dies der Fall wäre, hätte der Fehler _double free error_ generiert. Das Problem besteht darin, dass der "nächste" Zeiger des letzten nicht definiert wurde. Daher wird die erste Schleife niemals beendet. –

0

einen Zeiger löschen nicht den Zeiger oder andere Zeiger ändern, die auf die gelöschte Speicher zeigen:

#include <iostream> 

int main() { 
    int* head = new int[4]; 
    int* tail = head; 

    delete head; 

    std::cout << "head = " << (void*)head << ", tail = " << (void*)tail << "\n"; 
} 

Was sollte Ihr Code sein ist:

template<typename T> 
Queue<T>::~Queue(){ 
    Node<T> *currHead = head; 
    while(currHead != nullptr){ 
    Node<T> *nextHead = currHead->next; 
    delete currHead; 
    currHead = nextHead; 
    } 
    head = tail = nullptr; 
    size = 0; 
} 

oder wenn Sie Ihre Pop-Funktion funktioniert:

template<typename T> 
Queue<T>::~Queue() { 
    while (size) 
     pop(); 
} 
Verwandte Themen