C++ create chain using struct cause circular reference. nextNode refer to the same address and value

Viewed 31

The first call of appendChild work as expected, but then the next point to itself. need an example how to do it.

why LinkNode nextNode; not create a new instance

zsbd zsbd zsbd zsbd zsbd zsbd

#include "iostream"

using namespace std;

template<typename T>
struct LinkNode {
    T data;
    bool hasNext = false;
    LinkNode<T> *next = nullptr;

};

template<typename T>
void appendChild(LinkNode<T> &initNode, T &node) {
    LinkNode<T> *ptr = &initNode;
    while (ptr && ptr->hasNext) {
        ptr = ptr->next;
    }
    // end of the chain
    ptr->data = node;
    ptr->hasNext = true;
    // create new node
    LinkNode<T> nextNode;
    // append to the end
    ptr->next = &nextNode;
    cout << "done" << endl;
};

int main() {
    int a = 123;
    int b = 456;
    int c = 789;
    LinkNode<int> initNode;
    initNode.data = 1;
    appendChild(initNode, a);
    appendChild(initNode, b);
    appendChild(initNode, c);
    cout << "finish" << endl;
}

Detail on the pause.

enter image description here

1 Answers

LinkNode<T> nextNode; This is a local variable. It is destroyed when it goes out of scope. Thus ptr->next = &nextNode; will add the address of a local variable.

Accessing it's address is Undefined Behavior.

edit: a modern solution would be to use std::unique_ptr (we don't use new anymore). E.g.

#include <iostream>
#include <memory>

template<typename T>
struct LinkNode {
    T data;
    std::unique_ptr<LinkNode<T>> next;
};

template<typename T>
void appendChild(LinkNode<T> & initNode, T &node) {
    LinkNode<T> *ptr = &initNode;
    while (ptr && ptr->next) {
        ptr = ptr->next.get();
    }
    // end of the chain
    ptr->data = node;
    // create new node
    ptr->next = std::make_unique<LinkNode<T>>();
    std::cout << "done\n";
};

int main() {
    int a = 123;
    int b = 456;
    int c = 789;
    LinkNode<int> initNode;
    initNode.data = 1;
    appendChild(initNode, a);
    appendChild(initNode, b);
    appendChild(initNode, c);
    std::cout << "finish\n";
}
Related