2016-10-13 171 views
2

以下代碼可以正確構建,但會導致程序在運行時崩潰。有人可以告訴我它有什麼問題嗎?我懷疑DeleteNode函數有問題。單鏈表無法正常工作(C++)

#include <iostream> 
#include <cstdlib> 

using namespace std; 

class list { 
private: 
    typedef struct node { 
     int data; 
     node* next; 
    }* nodePtr; //this means that 'nodePtr' will mean a pointer to the struct node 

nodePtr head; 
nodePtr current; 
nodePtr temp; 

public: 
list() { //constuctor 
    head = NULL; 
    current = NULL; 
    temp = NULL; 
}; 

void AddNode(int addData) //to add a particular data value 
{ 
    nodePtr n= new node; 
    n->next = NULL; 
    n->data = addData; 

    if (head != NULL) { //if a list is already set up 
     current = head; 
     while (current->next != NULL) { //to get to the last node in the list 
      current = current->next; 
     } 
     current->next = n; 
    } 
    else { // if list is not created 
     head = n; //new node is front of the list 
    } 
} 

void DeleteNode(int delData) //to delete a particular data value 
{ 
    nodePtr delPtr = NULL; 
    temp = head; 
    current = head; 

    while (current != NULL && current->data!=delData) { //pass through whole list && find value 
     temp = current; 
     current = current->next; 
    } 

    if (current = NULL) { //data value not found in list 
     cout << delData << " was not in the list." << endl; 
     delete delPtr; //to free up memory space 
    } 
    else { 
     delPtr = current; 
     current = current->next; 
     temp->next = current; //to reconnect list 

     if (delPtr == head) { 
      head = head->next; 
      temp = head; 
     } 

     delete delPtr; 
     cout << "The value " << delData << "was deleted." << endl; 
    } 
} 

void PrintList() //to print all the data values 
{ 
    current = head; 

    while (current != NULL) { //to go through the data valued of the list 
     cout << current->data << endl; 
     current = current->next; 
    } 
} 

}; 



int main() 
{ 
    list Shahzad; 

    Shahzad.AddNode(2); 
    Shahzad.AddNode(78); 
    Shahzad.AddNode(28); 
    Shahzad.AddNode(2398); 

    Shahzad.DeleteNode(78); 
    Shahzad.PrintList(); 
    return 0; 
} 
+1

歡迎來到Stack Overflow!這聽起來像你可能需要學習如何使用調試器來遍歷代碼。使用一個好的調試器,您可以逐行執行您的程序,並查看它與您期望的偏離的位置。如果你打算做任何編程,這是一個重要的工具。進一步閱讀:** [如何調試小程序](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/)** – NathanOliver

+1

解決此類問題的正確工具是您的調試器。在*堆棧溢出問題之前,您應該逐行執行您的代碼。如需更多幫助,請閱讀[如何調試小程序(由Eric Lippert撰寫)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。至少,您應該\編輯您的問題,以包含一個[最小,完整和可驗證](http://stackoverflow.com/help/mcve)示例,該示例再現了您的問題,以及您在調試器。 –

+0

我沒有讀全部,但'if(current = NULL)'不能很好 – RyanP

回答

2

你的第一個問題是與以下行:

if (current = NULL) 

你實際上是分配nullcurrent在這一點上。

這實際上應該是:

if (current == NULL) 
0

在您的刪除功能中找不到節點的情況下,您正在刪除delPtr。

但是,delPtr從未實例化或分配,因此您試圖刪除不存在的內容。

總是將指針刪除放在if語句中以避免此問題。試試這個:

if (delPtr) delete delPtr; 
+0

那肯定不會引起問題,誰教你這樣? 'if(delPtr)delete delPtr;'是多餘的。 'delete'通過'nullptr'透明地工作。 –

1

首先,一些代碼和文件管理備註:考慮你的代碼分成.h文件,其中類成員的聲明和.cpp其中類成員實現,這將使你的類易於理解和可能出現的錯誤將更容易找到。其次,處理包含指針的結構時的一般建議是注意適當的資源管理,即應該謹慎處理指針定義,初始化和刪除。如果你是新手,可以考慮像使用已經提供智能指針設施:std::unique_ptr「通過指針保留對象的唯一所有權並銷燬該對象時unique_ptr超出範圍」

第三,使用調試器擺脫瑣碎的錯誤,如:

if (current = NULL) 

它的方式包含在使用NULL代替指針文字nullptr表示額外的不準確性。

最後,檢查每個成員函數分別完成初步實現,只有再與其他類別進行擴大後,否則你就有可能從多種來源的誤差累積,這將讓你的工作非常困難


0

除了這裏所有的建議,你可以使用一些安全的編程實踐,以儘早發現錯誤。

例如:您寫

if (current = NULL) 

相反,嘗試寫值在LHS像這樣在RHS變量被檢查:

if (NULL == current) 

在這裏,如果你輸錯

if (NULL = current) 

編譯器會抱怨。你現在有一個編譯時錯誤,而不是運行時錯誤。這很容易找到和調試。