循环双链表C ++

时间:2015-04-17 21:34:34

标签: c++

我想实现循环双链表。此列表只包含传入的字符串对象中的这些字符 这是我的代码,但我总是遇到seg错误。我在这个列表中使用了一个虚拟头

#ifndef MY_LIST_H
#define MY_LIST_H
#include <string>
#include <iostream>
using namespace std;
/**------   -----------------
 * dummy |->|pred|value|next|
 * ------   -----------------
 * */


struct Node
{
 char value;
 Node *next;
 Node *pred;

 Node( char value): value(value), next(0), pred(0){};
};

class MyList
{
    private:
    Node* head;
    unsigned int count; // count number of node

    public:
    // default constructor
    MyList(): count(0)
    {
        head = new Node('P');

    }

    //Constructs a list from a passed-in string object,
    MyList(const string& str): count(0)
    {
        Node *cur = head;
        if(count == 0)
        {
            head-> pred = head;
            head-> next = head;
        }
        else
        {
            for( unsigned i =0; i< str.length(); ++i)
            {
                cur->next = new Node(str.at(i));
                Node *temp = cur->next;
                temp-> pred = cur;
                ++count;
                if(count == str.length())
                {
                    cur->next->next = head;
                    head-> pred = cur-> next->pred;
                }
            }
        }
    }
    void print() const
    {
        Node *cur = head->next;
        while( cur != head)
        {
            cout << cur-> value;
            cur = cur-> next;
        }
    }

};
#endif

2 个答案:

答案 0 :(得分:1)

你似乎没有很好地理解构造函数。

初始化类时,只调用一个构造函数。如果需要,可以从另一个构造函数中调用构造函数,但这不是defaut:Can I call a constructor from another constructor (do constructor chaining) in C++?

在您的实例中,您的第二个构造函数应该是这样的:MyList(const string& str): MyList() { ... }

这样head可以正确地进行初始化,并且您不会创建段错误。

另外,您可以在调试模式下以调试模式运行代码,并找出代码崩溃的行。标题中的using namespace ...;也是不好的做法,因为你不知道你的标题会被包含在哪里。

答案 1 :(得分:0)

如果没有看到你如何使用这些类,但是你的MyList构造函数在字符串上重载会立刻被打破,很难确切地说出发生了什么。它将计数设置为0,因此您知道它将始终输入if子句而不是else

MyList(const string& str): count(0)
{
    Node *cur = head;
    if(count == 0)
    {
        head-> pred = head;
        head-> next = head;
    }
    else . . .
在if语句中,它尝试取消引用从未赋值的head。你确实在默认的构造函数中设置它,但是它似乎也没有做任何其他事情。

构造函数的目的是从头开始构造一个有效的对象。有时一个构造函数重载可能委托给另一个,以避免重复代码,但我不确定你在这里尝试做什么。

假设第二个构造函数实际上是一个辅助方法,那么它仍然无法工作,因为计数永远不会超过零(除了else子句,但你无法到达那里与count==0)。

我承认我看起来并不是很认真,但我猜测如果执行到目前为止:

cur->next->next 
当您尝试访问它时,并不总是设置

。如果cur-&gt; next是nullptr,那么你的程序就会死掉。