2013-01-21 34 views
0

我在C++中創建了這個鏈表列類,它運行良好,除非我運行它之後程序無響應。我找到了導致問題的線路,但我不知道爲什麼。即使我輸入的方式不同,它仍然會執行相同的操作。代碼行正在查殺我的程序

這是我的列表類:

#include <string> 

template<class T> 
class List : public Object{ 
private: 
    Node<T>* first; 
    Node<T>* last; 
    int length; 
public: 
    List() : Object(new std::string("List")) { 
     first = NULL; 
     last = NULL; 
     length = 0; 
    } 
    ~List() { 
     delete first; 
     delete last; 
    } 

    void Add(T value) { 
     if(first==NULL) 
      first = new Node<T>(NULL, value); 
     else if(last==NULL) 
      ---->last = new Node<T>(first, value);<----- 
     else 
      last = new Node<T>(last, value); 
     length++; 
    } 

    T Remove(T value) { 
     Node<T>* temp = first; 
     while(temp!=NULL) { 
      if(temp->GetValue()==value) { 
       temp->GetPrev()->SetNext(temp->GetNext()); 
       temp->GetNext()->SetPrev(temp->GetPrev()); 
       delete temp; 
       length--; 
       return value; 
      } 
      temp = temp->GetNext(); 
     } 
     return 0; 
    } 

    T Get(int index) { 
     Node<T>* temp = first; 
     int i = 0; 
     while(temp!=NULL) { 
      if(i==index) 
       return temp->GetValue(); 
      i++; 
      temp = temp->GetNext(); 
     } 
     return 0; 
    } 
}; 

當我刪除的程序上面標線去響應。這是我的節點構造:

#include <string> 

template<class T> 
class Node : public Object{ 
private: 
    Node* next; 
    Node* prev; 
    T value; 
public: 
    Node(Node* prev, T value) : Object(new std::string("Node")){ 
     if(prev!=NULL) { 
      prev->next = this; 
      this->prev = next; 
     } 
     next = NULL; 
     this->value = value; 
    } 
    ~Node() { 
     delete next; 
    } 

    T GetValue() { 
     return value; 
    } 

    Node* GetNext() { 
     return next; 
    } 

    Node* GetPrev() { 
     return next; 
    } 
}; 

我的對象類:

#include <string> 

class Object { 
private: 
    std::string* type; 
public: 
    Object() { 
     type = new std::string("Object"); 
    } 
    Object(std::string* type) { 
     this->type = type; 
    } 
    ~Object() { 
     delete type; 
    } 

    std::string* GetType() { 
     return type; 
    } 
}; 

我Test.cpp的

#include <iostream> 
#include <string> 

#include "Object.h" 
#include "Node.h" 
#include "List.h" 

using namespace std; 

int main() { 

List<int> l; 
l.Add(5); 
l.Add(93); 
l.Add(17); 
l.Add(7789); 
l.Add(60); 

cout << "node 4 is:" << l.Get(3) << endl; 

return 0; 
} 

錯誤圖像http://i50.tinypic.com/2mw5phi.png 感謝您的閱讀,並請只要你能幫忙,如果您需要我提供更多信息,請發表評論。

+1

您是否收到任何錯誤? – 0x499602D2

+0

沒有輸出是好的。該列表的作品,它只是讓我的程序不響應和Windows給出了沒有響應的錯誤 – user1494136

+0

您的構造函數引用'prev'。但是'prev'沒有顯示在你發佈的代碼的範圍內。請發佈*足夠的*代碼以顯示所有相關的變量和操作。 – abelenky

回答

2

編輯:有很多問題,你的程序,但什麼可能導致您的崩潰:您Add - 功能無法正常工作。它應該是這樣的:

if(first==NULL) { 
    first = new Node<T>(NULL, value); 
    last = first; 
} else { 
    last = new Node<T>(last, value); 
} 
length++; 

否則,它不會正確插入第二個元素。爲什麼?使用您的原始代碼,第一次添加後,由於else,您的last仍爲NULL。所以在第二次添加時,您最後設置爲new Node<T>(NULL, value)。因此,它不會分配第一個元素的指針next。而你的名單將不一致。

除此之外,還有雙重的FreeS,在Object類的string場不必要的堆分配,所有權問題等方面給予你只是一個例子:你的List析構函數會導致堆損壞因雙倍免費。調用delete first將刪除由於Node的析構函數中的delete next而導致的所有節點,只要該列表一致即可。然後你打電話給delete last,但那個對象已經被釋放了。這會破壞程序的內存管理,也可能導致程序退出時崩潰。

+0

後添加兩個我想第二個是最後一個,第一個是這就是爲什麼我寫了'last = new Node (first,value);'然後我想保留我的最後一個節點作爲最後一個節點(last,值);'這樣做是因爲我只想在第二次add()調用時先設置爲prev。另一種方法是:'if(first == NULL){first = new Node (NULL,value); last = first; } else else last = new Node(last,value);' – user1494136

+0

是的,但是如果在Add()中,你仍然會在第一個中丟失last = first,否則last將只剩下對於包含一個元素的列表,爲NULL。 –

+0

這不是真的,我寫了'if(last == NULL)last = new Node(first,value);'任何方式我也試過其他代碼,但仍然是相同的錯誤。最奇怪的是它打印'l.Get(3);'罰款就這麼死了。我已經掌握了許多不同的方法來使這個add()方法執行相同,但沒有一個可以工作。就像我曾經把它放在最後一個節點的構造函數中一樣。 – user1494136

2

這個功能對你來說看起來是否正確?

它說GetPrev,但它實際上得到next

Node* GetPrev() { 
    return next; 
} 
+0

謝謝,我只是修復它並運行該程序,但仍然沒有運氣 – user1494136

1

我發現,如果我在Node構造註釋掉這行代碼編譯:

if (next != NULL) { 
    // next->next = this; 
    prev = next; 
} 

編輯1:

我也意識到,你在你的Node類這樣做:

由於這些對象是在中聲明的10級,他們在這個時候是不完整的類型。我設法複製這一問題降低到一個簡單的像this

template <class T> 
struct S { 
    S* s = new S(); 
    ~S() { delete s; } 
}; 

int main() { 
    S<int> s; // Segmentation fault  (core dumped) ./test > .stdout 
} 

這會導致系統崩潰,因爲S是內本身不完全類型。

我得到了和你在代碼中一樣的segementation錯誤。我很確定這是因爲Node類中的指針是建立在不完整的類型上的;並從他們的數據訪問正在調查是不是你的內存,因此崩潰。

+0

不會發生未響應的錯誤,但我的代碼不起作用。看看我是不是將下一個參數(其實應該被稱爲prev)設置在這個旁邊,那麼所有節點的所有下一個將保持爲NULL,這個列表將只通過prev鏈接,這導致它實際上鬆散鏈接。 – user1494136

+0

@ user1494136我發現了另一個問題。查看我的編輯 – 0x499602D2

+0

,所以我應該將'Node * next'更改爲'Node * next'?謝謝你的輸入方式 – user1494136

相關問題