单链接列表seg故障问题

时间:2013-05-30 09:16:20

标签: c++ linked-list segmentation-fault

我试图自己实现一个链表。现在,我只在列表的末尾添加了一个元素,并打印了一个列出内容的函数。但是当我想打印出一个列表时,我的程序会给我一个分段错误。继承我的代码:

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

3 个答案:

答案 0 :(得分:4)

在将last != NULL设置为last->next之前,您似乎忘了检查s

NULL指针引用到undefined behaviour

您的addFront函数应如下所示:

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

顺便说一下:使用if(last == first && last == NULL)代替if(last == first == NULL)

答案 1 :(得分: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;
}

答案 2 :(得分:2)

这是因为addfront方法

中的这一行

last->next = s;

这里last是一个NULL指针。

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

引用NULL指针将导致内存错误/分段违规。

始终检查它是否为NULL,然后是deference。

if (last)
  last->next = s;

如果您使用的是Linux计算机,则可以在gdb中运行该程序。一旦发生分段违规,请使用backtrace命令查看调用堆栈,以了解哪个语句崩溃。