Inserting an element to the end of the doubly-linked list

clist

I'm writing a program which can insert elements to the end of the list, and display one of then. It inserts properly, but I can display the specified one.

typedef struct Node
{
        int data;
        struct Node *next;
        struct Node *prev;
} node;

void insert(node *head, int data)
{
        node *newNode = (node*) malloc(sizeof(node));
        newNode->data = data;
        newNode->next = NULL;

        if(head == NULL)
        {
            head = newNode;
        }
        else
        {
            while(head != NULL)
                head = head->next;

            head->next = newNode;
            (head->next)->prev = head;
        }
}

void print(node *head, int element)
{
    node *temp = head;
    int count = 0, i = 1;
    while(i < element)
    {
        temp = temp->next;
        i++;
    }
    printf("%d", temp->data);
}

int main()
{
        node *start = (node*) malloc(sizeof(node));
        start = NULL;

        int data1 = 4, data2 = 5;
        insert(start,data1);
        insert(start,data2);

        print(start, 1);
}

Why doesn't it work? Also, could you tell me if I am doing this properly?

Best Answer

It's because you pass the start pointer by value. This means that any changes to it inside the insert function will be lost once the function returns.

You can pass the pointer by reference:

void insert(node **head, int data)
{
    /* ... */
    if (*head == NULL)
        *head = newNode;
    else
    {
        /* ... */
    }
}

int main(void)
{
    node *start = NULL;
    insert(&start, 1);
    /* ... */
}

Or return the pointer from the function:

node *insert(node *head, int data)
{
    /* ... */
    return head;
}

int main(void)
{
    node *start = NULL;
    start = insert(start, 1);
    insert(start, 2);  /* Do not get the returned pointer, as the returned pointer no longer points to the start of the list */
    /* ... */
}

The problem with both these solution is that you change head if it's not NULL, to point to the node before the last node. In the loop inside insert you should use a temporary pointer instead.


As a safety precaution, you should check that you don't have a NULL node in the loop in the print function. Think about what will happen otherwise if you pass a number that is larger than the number of nodes in the list.