cdoubly-linked-list

Head keeps getting set to NULL


I made a doubly link list and ran it a couple times with functions to add nodes at end, output the length of the list and to print all the elements. It was working fine. Then I made a function to add a node at a specific location called AddNodeAt(). and since then, it no longer works. head keeps getting set to NULL. After AddNode() is done the other functions work as if head points to NULL instead of the list.

This is the full code:

#include <stdio.h>
#include <stdlib.h>

struct node {
    node *prev;
    int val;
    node *next;
};
typedef struct node node;

node *head;

node *AddNode(node *head, int value)
{
    node *ptr = (node *)malloc(sizeof(node));

    if (!ptr) {
        printf("No Memory Available");
    } else
    if (!head) {
        ptr->val = value;
        ptr->next = NULL;
        ptr->prev = NULL;
        head = ptr;
    } else {
        node *temp = head;
        while (temp->next) {
            temp = temp->next;
        }
        temp->next = ptr;
        ptr->prev = temp;
        ptr->next = NULL;
        ptr->val = value;
    }
    return head;
}

int ListLength(node *head)
{
    int count = 0;
 
    if (head == NULL) {
        printf("\nEmpty List\n");
    } else {
        node *temp = head;
        count = 1;
        while (temp->next != NULL) {
            temp = temp->next;
            count++;
        }
        printf("\n%d nodes\n", count);
    }
    return count;
}

node *AddNodeAt(node *head, int position, int value)
{
    int i = 0;
    node *temp = head;
    node *ptr = (node *)malloc(sizeof(node));
    if (head == NULL && position != 1) {
        printf("Empty Linklist, cannot insert node at the given position");
    } else
    if (position > ListLength(head) + 1) {
        printf("list too short, cannot insert node at the given position");
    } else
    if (position == ListLength(head) + 1) {
        while (temp->next) {
            temp = temp->next;
        }
        temp->next = ptr;
        ptr->next = NULL;
        ptr->val = value;
        ptr->prev = temp;
    } else {
        while (i < position) {
            i++;
            temp = temp->next;
        }
        ptr->next = temp->next;
        temp->next = ptr;
        ptr->prev = temp;
        ptr->val = value;
        temp = ptr->next;
        temp->prev = ptr;
    }
    return head;
}

void PrintList(node *head)
{
    node *temp = head;
    if (!head) {
        printf("list empty");
    } else {
        while (temp->next != NULL) {
            printf("%d->", temp->val);
            temp = temp->next;
        }
        printf("%d", temp->val);
    }
}

int main() {
    int value = 0;
    int num = 0;
    int position = 0;
    printf("Number of nodes to be made: ");
    scanf("%d", &num);
    for (int i = 1; i <= num; i++) {
        printf("value in node number %d: ", i);
        scanf("%d", &value);
        AddNode(head, value);
    }
    PrintList(head);
    ListLength(head);

    printf("\nPosition of new node: ");
    scanf("%d", &position);
    printf("\nNumber of nodes:");
    scanf("%d", &value);
    AddNodeAt(head, position, value);

    PrintList(head);
    ListLength(head);

    return 0;
}

Any guidance would be appreciated. I tried commenting out the sections which I added right before this issue occurred. I expected others to start working as they were working before, but they didn't. head keeps getting set to NULL.


Solution

  • head does not get set to NULL: the global variable head is initialized to NULL before the program starts and is never updated to point to the allocated list.

    You should make head a local variable in main and update it to the return value of functions AddNode and AddNodeAt.

    Note these other problems:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct node node;
    struct node {
        node *prev;
        int val;
        node *next;
    };
    
    int get_integer(void) {
        for (;;) {
            int value;
            int c;
            switch (scanf("%d", &value)) {
              case 1:
                /* read and discard the rest of the input line */
                while ((c = getchar()) != EOF && c != '\n')
                    continue;
                printf("\n");
                return value;
              case EOF:
                fprintf(stderr, "unexpected end of file, aborting\n");
                exit(1);
              default:
                /* read and discard the rest of the input line */
                while ((c = getchar()) != EOF && c != '\n')
                    continue;
                fprintf(stderr, "invalid input, try again\n");
                break;
            }
        }
    }
    
    node *AddNode(node *head, int value) {
        node *ptr = (node *)malloc(sizeof(node));
    
        if (!ptr) {
            fprintf(stderr, "No Memory Available\n");
            exit(1);
        }
        ptr->val = value;
        ptr->next = NULL;
        ptr->prev = NULL;
    
        if (!head) {
            head = ptr;
        } else {
            node *temp = head;
            while (temp->next) {
                temp = temp->next;
            }
            temp->next = ptr;
            ptr->prev = temp;
        }
        return head;
    }
    
    int ListLength(const node *head) {
        int count = 0;
     
        while (head != NULL) {
            count++;
            head = head->next;
        }
        return count;
    }
    
    void PrintListLength(const node *head)  {
        if (head == NULL) {
            printf("Empty List\n");
        } else {
            printf("%d nodes\n", ListLength(head));
        }
    }
    
    node *AddNodeAt(node *head, int position, int value) {
    
        if (position > ListLength(head) + 1) {
            printf("list too short, cannot insert node at the given position\n");
            return head;
        }
    
        node *ptr = (node *)malloc(sizeof(node));
        if (!ptr) {
            fprintf(stderr, "No Memory Available\n");
            exit(1);
        }
        /* initialize the new node */
        ptr->value = value;
        ptr->next = NULL;
        ptr->prev = NULL;
    
        if (position <= 1) {
            /* insert at front */
            if (head) {
                ptr->next = head;
                head->prev = ptr;
            }
            head = ptr;
        } else {
            node *temp = head;
    
            for (int i = 1; i < position; i++) {
                temp = temp->next;
                i++;
            }
            ptr->prev = temp;
            temp->next = ptr;
            ptr->next = temp->next;
            if (ptr->next) {
                ptr->next->prev = ptr;
            }
        }
        return head;
    }
    
    void PrintList(const node *head) {
        const node *temp = head;
        if (!head) {
            printf("list empty\n");
        } else {
            while (temp->next != NULL) {
                printf("%d->", temp->val);
                temp = temp->next;
            }
            printf("%d\n", temp->val);
        }
    }
    
    void FreeList(node *head) {
        while (head) {
            node *next = head->next;
            free(head);
            head = next;
        }
    }
            
    int main(void) {
        int value = 0;
        int num = 0;
        int position = 0;
        node *head = NULL;
    
        printf("Number of nodes to be made: ");
        num = get_integer();
    
        for (int i = 1; i <= num; i++) {
            printf("value in node number %d: ", i);
            value = get_integer();
            head = AddNode(head, value);
        }
        PrintList(head);
        PrintListLength(head);
    
        printf("Position of new node: ");
        position = get_integer();
        printf("Node value: ");
        value = get_integer();
        head = AddNodeAt(head, position, value);
    
        PrintList(head);
        PrintListLength(head);
    
        FreeList(head);
        return 0;
    }