Home > Software design >  C create chain using struct cause circular reference. nextNode refer to the same address and value
C create chain using struct cause circular reference. nextNode refer to the same address and value

Time:07-09

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

CodePudding user response:

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";
}
  •  Tags:  
  • c
  • Related