2016-05-24 51 views
1

我想了解C++,我遇到了內存管理和析構函數的問題。我嘗試使用鏈接列表編寫隊列實現,當我試圖在析構函數方法中刪除鏈接列表節點(粗體)時,我收到「中止(核心轉儲)」錯誤消息。如果有人知道我做錯了什麼,請告訴我!C++ LinkedList隊列實現和析構函數錯誤:「Aborted(Core Dumped)」

下面是我的析構函數方法的代碼:

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> 
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; 
    } 
} 

編輯:

我也嘗試了以下定義對於析構函數,但我得到相同的錯誤:

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;''delete'currHead;''之後''你在代碼中多次做類似的東西。 –

+0

我該怎麼做?我在這裏感到茫然 - 如果你看到我的編輯,我嘗試了一些不同的析構函數,但我仍然不僅在你的析構函數中獲取「Aborted(Core Dumped)」錯誤 – mathmonkey

+0

,即使在你的* full鏈表隊列實現中*你正在犯一個類似的錯誤。 –

回答

3

在析構函數的第一部分中,您將從頭開始刪除所有列表項。在析構函數的第二部分中,您試圖通過使用尾部保留的指針再次刪除最後一個列表項,但它已在第一部分中刪除。

+0

這就是我的想法,但我檢查 - 即使在析構函數的第一部分中刪除頭後,仍然tail!= NULL,所以我應該仍然需要刪除它之後呢? – mathmonkey

+0

@mathmonkey頭部和尾部指針存儲相同的地址,所以即使內存已經被刪除,'tail!= NULL'也是如此。 – Rakete1111

+0

這似乎是問題,但事實上並非如此。如果是這種情況,則會產生_double free error_的錯誤。問題是last的'next'指針還沒有被定義。因此第一個循環將永遠不會終止 –

0

刪除指針不會更改指向被刪除內存指針或任何其他指針:

#include <iostream> 

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

    delete head; 

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

你的代碼應該是:

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; 
} 

,或者如果您的POP功能作品:

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