2013-05-30 47 views
2

我試圖自己實現一個鏈表。目前,我只在列表的末尾添加了一個元素,並且還有一個打印列表內容的函數。但是當我想打印一份清單時,我的程序給了我一個分段錯誤。我的繼承人代碼:單鏈表列錯誤問題

#include <cstdlib> 
#include <iostream> 
#include <string> 
using namespace std; 

class Stuff; 

class List 
{ 
    private : 

     Stuff *first, *last; 

    public : 
     List(); 
     void addfront(Stuff *s); 
     void print(); 
     ~List(); 
}; 

class Stuff 
{ 
    private : 

     string name; 
     double price; 

    public : 

     Stuff(); 
     Stuff(string, double); 
     void print(); 
     Stuff *next; 
}; 

Stuff::Stuff() 
{ 
    name = ""; 
    price = 0; 
    next = NULL; 
} 

Stuff::Stuff(string n, double p) 
{ 
    name = n; 
    price = p; 
} 

void Stuff::print() 
{ 
    cout << name << " " << price << "\n"; 
} 

List::~List() 
{ 
} 

void List::addfront(Stuff *s) 
{ 
    if(first == NULL) 
     first = s; 
    last->next = s; 
    s->next = NULL; 
    last = s; 
} 

void List::print() 
{ 
    Stuff *p; 
    if(last == first == NULL) 
     cout << "list is empty!\n"; 
    else 
     for (p = first; p != NULL; p = p->next) 
      p->print(); 
} 

List::List() 
{ 
    first = last = NULL; 
} 

int main(int argc, char **argv) 
{ 
    List l; 

    Stuff *s1 = new Stuff("Coffe", 4.50); 
    Stuff *s2 = new Stuff("Apple", 2.50); 

    l.addfront(s1); 
    l.addfront(s2); 

    l.print(); 

    return 0; 
} 
+1

你不應該在C++中使用'NULL'宏...而是使用'0'。 –

+1

Juste一句話,'last == first == NULL'不會像你期望的那樣工作。改爲使用'last == first && first == NULL'。 –

+0

@ bash.d這並不好,使用'nullptr'。 – Djon

回答

4

好像你忘了設置last->nexts前檢查是否last != NULL

NULL指針結果設置爲undefined behaviour

addFront功能應該看起來像:

void List::addfront(Stuff *s) { 
    if(!first) 
     first = s; 
    if (last) 
     last->next = s; 
    s->next = NULL; 
    last = s; 
} 

BTW:使用if(last == first && last == NULL)代替if(last == first == NULL)

+0

它似乎可以與這兩個修改。 – Liviu

+0

+1的鏈接... – Sanish

+0

@Sanish:謝謝 –

3

的一個問題是

if(last == first == NULL) 

使其

if(last == NULL && first == NULL) 

還你需要做的,

void List::addfront(Stuff *s) 
{ 
    if(!first) 
     first = s; 
    if (last) 
     last->next = s; 
    s->next = NULL; 
    last = s; 
} 
+0

這是完全**我的答案。 –

+1

@segfolt Yeps我知道我遲到了!我試圖找到一些與問題相關的鏈接。沒有probs我upvoted你的。當我找到他們時,會添加一些鏈接到我的 –

+0

謝謝。沒問題。我只是不明白,因爲它看起來像一個純副本粘貼:頁 –

2

這是因爲這條線在addfront方法

last->next = s;

這裏last是一個NULL指針。

(gdb) p last 
$1 = (Stuff *) 0x0 

引用空指針會導致內存錯誤/分段衝突。

總是檢查它是否爲空,然後尊重。

if (last) 
    last->next = s; 

如果你在Linux機器上,那麼您可以在gdb運行程序。一旦發生分段違例,請使用backtrace命令查看調用棧以瞭解哪條語句崩潰。