1

Today I was taught Linked list in class and I wanted to implement it on my own.

Here's the part of the code that I wrote. Note that traverseLL traverses the Linked list and insertAtEnd inserts a new node at the end of the linked list.

I believe I can implement Linked list logic / methods / functions on my own. But my question is, inside insertAtEnd function when I create a newNode with the parameters - my data to be inserted, and nullptr (because inserting at the end), It inserts garbage values (or memory addresses maybe) in my node, ignoring the data passed to the constructor.

using namespace std;
#define NL '\n'

class Node {
    public:
        int data;
        Node* next;

    Node (int data, Node* nextPtr=nullptr) {
        data = data;
        next = nextPtr;
    }
};


void insertAtEnd(Node* &head, int data) {

    Node* newNode = new Node(data, nullptr);  // <---- Issue in this line
    // When I do as above, my linkedlist nodes always store garbage values and not the data being passed.

    // However, when I un-comment the below line, I get the correct output.
    // newNode->data = data;

    if (head == nullptr)
        head = newNode;
    
    else {
        Node* temp = head;

        while (temp->next != nullptr)
            temp = temp->next;

        temp->next = newNode;
    }
}


void traverseLL(Node* head) {
    if (head == nullptr)
        return;

    while (head->next) {
        cout << head->data << " -> ";
        head = head->next;
    }
    cout << head->data << NL;
}




int main() {

    Node* head = nullptr;

    insertAtEnd(head, 10);
    insertAtEnd(head, 20);
    insertAtEnd(head, 30);
    
    traverseLL(head);

    return 0;
}

For example, the output for the above code when keeping newNode->data = data line commented, is :

16259544 -> 16258392 -> 16258392

But when I un-comment that line, my output becomes, which is intended:

10 -> 20 -> 30

Why is this happening? Even though I've defined my constructor, why is it not working?

Root
  • 11
  • 1

1 Answers1

0

I think the cause for this is the statement data = data in the constructor.

Reason for this: Before executing the first statement of constructor, the member variables of the class are allocated memory and contain junk/default values, and when the statement data = data is seen the compiler changes the parameter but not the member variable. As a result, you are seeing junk/garbage values.

To resolve this we can either explicitly specify the member using this or use member initialization syntax. You can use any of the following workarounds.

Workarounds: You can change your class constructor code like any of the below formats:

1.

class Node {
    public:
        int data;
        Node* next;

    Node (int data, Node* nextPtr=nullptr) {
        this->data = data; // we are explicitly specifying which data to use
        next = nextPtr;
    }
};
class Node {
    public:
        int data;
        Node* next;

    Node (int d, Node* nextPtr=nullptr) {
        data = d; // as the member variable and local variable are of different names, no conflict
        next = nextPtr;
    }
};
class Node {
    public:
        int data;
        Node* next;

    // use the member initialization syntax
    // Here we are initializing the data while allocating memory itself,
    // so answer is perfectly right!
    Node (int d, Node* nextPtr=nullptr) : data(data), next(nextPtr) {}
};

More on the member initialization and constructor:

https://en.cppreference.com/w/cpp/language/constructor

How do C++ class members get initialized if I don't do it explicitly?

Hope this helps, Thanks.