Problems creating a linked List

Hey,

i want to create a type of linked List for a class Control System to Manage a bigger proect. Every Module of this Project has a class as Member and another class get some parameters of this…

My problem is that the data are not correctly saved. i’ve wrote a example script with the same problem but much smaller to post this here… i hope someone can help me… I can’t manage the problem by myself… for me it is a “correct” linked list - but every time the sketch add the new Obj. as firstNode…

class inner {
  String name = "n.S";
 inner* _nextNode = NULL;

 public:
inner(String name)
{
  this->name = name;
}

inner* getNextNode()
{
  return _nextNode;
}

void setNextNode(inner* nextNode)
{
  this->_nextNode = nextNode;
}

String getName()
{
  return name;
}};

class outer {
private:
inner* _firstNode = NULL;

public:
outer(){};

  void addInner(String name)
{
  inner newObj(name);
  Serial.println("Add Inner");
  Serial.print("Name: ");
  Serial.println(newObj.getName());
  if(_firstNode == NULL)
  {
    Serial.println("First Node has no Member");
    _firstNode = &newObj;
  }
  else
  {
    Serial.println("First Node has a Member");
    if(_firstNode->getName() != NULL)
    {
      Serial.println("Name saved in FirstNode: ");
      Serial.println(_firstNode->getName());
    }
    else
    {
      Serial.println("Object was deleted");
    }


    
    inner* pointer = _firstNode;
    int counter = 0;
    //set pointer to the last object - this doesn't work
    while(pointer->getNextNode() != NULL)
    {
      Serial.print("Saved name at Slot: ");
      Serial.print(counter + ": ");
      Serial.println(pointer->getName());
      pointer = pointer->getNextNode();
      counter++;
    }
    Serial.print("NewNode added at ");
    Serial.println(counter);
    
    pointer->setNextNode(&newObj);
  }
    }

void showAllInner()
{
  if(_firstNode == NULL)
  {
    return;
  }

  inner* pointer = _firstNode;

  do {
    Serial.print("Name: ");
    Serial.println(pointer->getName());
    pointer = pointer->getNextNode();
  }while(pointer != NULL);
}

void getFirst()
{
  Serial.print("Name der ersten Node: ");
  Serial.println(_firstNode->getName());
}
};

 void setup() {
  // put your setup code here, to run once:
 Serial.begin(115200);
  outer test;
 for(int i = 0; i < 5; i++)
  {
      test.addInner(String(i));
  }
  Serial.println("fertig");
 delay(500);
 //test.showAllInner();
  test.getFirst();
}

void loop() {
   // put your main code here, to run repeatedly:

 }

This is the sketch and the Output:

   Add inner
  Name: 0
First Node has no Member
Add Inner
Name: 1
First Node has a Member
Name saved in FirstNode: 
1
NewNode added at 0
Add Inner
Name: 2
First Node has a Member
 Name saved in FirstNode: 
2
  NewNode added at 0
 Add Inner
Name: 3
 First Node has a Member
Name saved in FirstNode: 
3
NewNode added at 0
Add Inner
Name: 4
First Node has a Member
Name saved in FirstNode: 
 4
 NewNode added at 0
 fertig

maybe the objects will deleted after the function call? in my other script my esp crash if i want to read out the data… - if someone wants to read the original Code: https://pastebin.com/sAPyuDwS
And the Project (branch: dev_linear_web): GitHub - j54j6/ESPBase at dev_linearWeb

hope that someone can help me ^^ - thanks a lot :slight_smile:

j54j6

You’re setting the “next node” address of this object here to an object that has been allocated on the stack. This object will be destroyed / deallocated as soon as executiton leaves the function, thus you’ll be pointing to invalid memory → program crash incoming. You need to have new (and delete for cleanup) semantics here.

When you look at this example you also see new and delete being used

Overall it seems though that you’re looking for a std::list, or even lesser, a std::vector? The project you’re linking to is an ESP8266 project. The xtensa-lx106-elf-g++ compiler is well capable of giving you a std::list.

#include <Arduino.h>
#include <list>
void setup(){
    Serial.begin(115200);
}

void loop() {
    std::list<String> myList = {
        String("ab"), String("cd"), String("ef")
    };
    for(const String& str : myList) {
        Serial.println("String in list: " + str);
    }
}

and

[env:nodemcuv2_serial]
platform = espressif8266
board = nodemcuv2
framework = arduino
monitor_speed = 115200

outputs

String in list: ab
String in list: cd
String in list: ef

continously. So it just works™ and has all the nice C++ semantics one would ever want.

1 Like