0

I'm trying to create a few nodes for a doubly linked-list and print them out. So I create my dnode class:

template <typename T>
class dnode
{
    public:
        T nodeValue;
        dnode<T> *prev;
        dnode<T> *next;

        dnode() : prev(this), next(this) {}

        dnode(const T& item, dnode<T> *prevNode = NULL, dnode<T> *nextNode = NULL) :
            nodeValue(item), prev(prevNode), next(nextNode) {}

};

Then I have my writeList function:

template <typename T>
void writeDLinkedList(dnode<T>* header, const string& seperator = " ")
{
    dnode<T> *p = header->next;

    while (p != header)
    {
        cout << p->nodeValue << seperator;
        p = p->next;
    }

    cout << endl << endl;
}

In main, I create a header pointer and two nodes, using the constuctor to assign the previous and next nodes in the circular list:

dnode<int> *header, *one, *two;

header = new dnode<int>(0, two, one);
one = new dnode<int> (10, header, two);
two = new dnode<int> (25, one, header);

writeDLinkedList(header);

When I call writeDLinkedList, I get a segmentation fault. I was confused by this, so I eventually tried to output each node value individually to see if the pointers were working correctly. It turns out they weren't. Instead, I have to do this to get the print function working correctly:

header = new dnode<int>;

one = new dnode<int> (10);
two = new dnode<int> (25);
header->next = one;
one->next = two;
two->next = header;

writeDLinkedList(header);

I want to know why my constructor isn't working the way it should. Is it the initialization list?

1
  • prev and next should be initialized to NULL, not to this. Checks for valid nodes should then be updated to look for NULL while looping. Commented Apr 23, 2013 at 21:46

3 Answers 3

1

Your constructor is working. The problem is that you are using variables before they have been given values.

dnode<int> *header, *one, *two; 
// one and two have undefined values at this point

header = new dnode<int>(0, two, one);
// so undefined values get put into header->next and header->prev

In a doubly linked list you have pointer cycles, node A points to node B which points back to node A. By definition pointer cycles cannot be created in constructors only. Because either node A or node B must be created first. Which ever is created first cannot be created pointing at the other node since that other node doesn't exist yet.

Doubly linked lists are a little more complicated than you realised I think.

Sign up to request clarification or add additional context in comments.

1 Comment

Yeah, I think I've underestimated them. Thanks for the concise answer.
0

You are not managing the nodes correctly. Try this instead:

template <typename T>
class dnode
{
    public:
        T nodeValue;
        dnode<T> *prev;
        dnode<T> *next;

        dnode() : prev(NULL), next(NULL) {}

        dnode(const T& item, dnode<T> *prevNode = NULL) :
            nodeValue(item), prev(prevNode), next(NULL)
        {
            if (prev)
            {
                if (prev->next)
                    prev->next->prev = this;
                prev->next = this;
            }
        }

        ~dnode()
        {
            if (prev)
                prev->next = next;

            if (next)
                next->prev = prev;
        }
};

.

template <typename T>
void writeDLinkedList(dnode<T>* header, const string& seperator = " ")
{
    dnode<T> *p = header;

    while (p != NULL)
    {
        cout << p->nodeValue << seperator;
        p = p->next;
    }

    cout << endl << endl;
}

.

dnode<int> *header, *one, *two;

header = new dnode<int>(0);
one = new dnode<int> (10, header);
two = new dnode<int> (25, one);

writeDLinkedList(header);

Comments

0

I think you are trying to create doubly circular list. You can first create individual nodes and then connect them. In doubly circular list after connecting two nodes, you have to connect the last node to the first to close circle. You may want to try something like. I've done it for int, but it can be easily put into a template.

#include<iostream>

class dnode
{

public:

    dnode(int a):prev(this), next(this), nodeValue(a)
     {}
    void connectNode(dnode *newNode)
     {
        if(newNode != NULL)
        {
            dnode*head = this->next;
            this->next = newNode;
            newNode->prev = this;
            newNode->next = head;
            head->prev = newNode;
        }
     }

    void writeDNode()
     {
     dnode *p = this->next;
        while(p != this)
         {
            std::cout<<"Element "<<p->nodeValue<<std::endl;
            p = p->next;
         }
     }
private:
    int nodeValue;
    dnode *prev;
    dnode *next;

 };


int main(int argc, char*argv[])
 {
    dnode* header = new dnode(-1);
    dnode *one = new dnode(23);
    dnode *two = new dnode(45);
    dnode *three = new dnode(67);
    header->connectNode(one);
    one->connectNode(two);
    two->connectNode(three);
    header->writeDNode();
    std::getchar();



 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.