Search code examples
c++nodessingly-linked-list

Why is my LinkedList reading an extra node at the end of my list?


I'm trying to write a function moveLasttoFront for my LinkedList class, but it seems to read another Node in before the nullptr at the end of the list.

For example, let's says I have a linked list {0, 1, 2, 8, 3, 4}. I want to run a pointer through the list until it equals nullptr and stop. But instead of stopping after 4, it iterates once more, then stops (I think). Here is my code:

  void moveLasttoFront ( ) {
    Node * last = head;
    Node * secLast = nullptr;

    while ( (*last).next != nullptr ) {
        secLast = last;
        last = (*last).next;
    }

    (*last).next = head;
    (*secLast).next = nullptr;
    head = (*last).next;
 }

When used on the list above, for example, secLast ends up pointing to Node 4 and last ends up pointing to 0. I don't understand where this "0" is coming from since there shouldn't be another node after 4? secLast should point to 3 and last should point to 4.

Any help would be greatly appreciated.

Thanks!

P.S. Sorry if this is too vague/I used something wrong. This is my first time asking a question on here :)


Solution

  • I've made this example in C.

    Main.c

    #include "linked_list.h"
    
    Node* moveLastToFront(Node* head) {
        Node* secondLast;
        Node* last = head;
        while (last->next != NULL) {
            secondLast = last;
            last = last->next;
        }
    
        (*secondLast).next = NULL;
        (*last).next = head;
        head = last;
    
        return head;
    }
    
    int main(void) {
        Node* head = NULL;
        for (int i = 1; i < 10; i++)
            head = addnode(head, i);
    
        listprint(head);
        printf("\n");
        head = moveLastToFront(head);
        listprint(head);
    
        return 0;
    }
    

    linked_list.h

    #ifndef LINKED_LIST_H
    #define LINKED_LIST_H
    
    typedef struct Node {
        int data;
        struct Node* next;
    } Node;
    
    Node *addnode(Node* node, int data);
    void listprint(Node* node);
    void freelist(Node* node);
    
    #endif // LINKED_LIST_H
    

    linked_list.c

    #include "linked_list.h"
    #include <stdio.h>
    #include <stdlib.h>
    
    Node* addnode(Node* node, int data) {
        if (node == NULL) {
            node = malloc(sizeof (Node));
    
            node->data = data;
            node->next = NULL;
        }
        else
            node->next = addnode(node->next, data);
    
        return node;
    }
    
    void freelist(Node* node) {
        if (node != NULL) {
            freelist(node->next);
            free(node);
        }
    }
    
    void listprint(Node* node) {
        static int i = 0;
        if (node != NULL) {
            printf("Node [%d] points to node [%d] which contains: %d\n", i, i + 1, node->data);
            i++;
            listprint(node->next);
        }
        else
            i = 0; // Reset i in case function is called again with another list
    }
    

    Output:

    Node [0] points to node [1] which contains: 1
    Node [1] points to node [2] which contains: 2
    Node [2] points to node [3] which contains: 3
    Node [3] points to node [4] which contains: 4
    Node [4] points to node [5] which contains: 5
    Node [5] points to node [6] which contains: 6
    Node [6] points to node [7] which contains: 7
    Node [7] points to node [8] which contains: 8
    Node [8] points to node [9] which contains: 9
    
    Node [0] points to node [1] which contains: 9
    Node [1] points to node [2] which contains: 1
    Node [2] points to node [3] which contains: 2
    Node [3] points to node [4] which contains: 3
    Node [4] points to node [5] which contains: 4
    Node [5] points to node [6] which contains: 5
    Node [6] points to node [7] which contains: 6
    Node [7] points to node [8] which contains: 7
    Node [8] points to node [9] which contains: 8
    

    If you have any doubts feel free to ask!