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

3 回答 3

4

似乎您last != NULL在设置last->nexts.

推迟NULL指针导致未定义的行为

您的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).

于 2013-05-30T09:19:49.210 回答
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;
}
于 2013-05-30T09:26:14.740 回答
2

addfront这是因为方法中的这一行

last->next = s;

last是一个 NULL 指针。

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

推迟 NULL 指针将导致内存错误/分段冲突。

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

if (last)
  last->next = s;

如果你在 Linux 机器上,那么你可以在gdb. 一旦发生分段违规,请使用backtrace命令查看调用堆栈以了解哪个语句崩溃。

于 2013-05-30T09:35:00.167 回答