I have several classes that call each other running on an Arduino Mega. I am using the ArduinoSTL
library to get the std library, most notably the std::vector.
The core problem is as follows: my Manager
object that is created in the Arduino global space, is called in the loop()
. The Manager
object in one of it's functions spawns a derived object Derived derived
(the constructor also takes a pin int and a delay value, but just simplifying for now) and calls a function in it derived.startExecution()
. All is happy. Then I store a pointer to the object into a std::vector<base*> myVector
via myVector.push_back(&derived)
. All is happy. As long as I don't leave the function, I can then take the pointer out of the vector container and call another function in the object. For example: myVector.back()->continueExecution()
and all is great. Now the problem. If I copy paste the line myVector.back()->continueExecution()
into a different function, the Arduino restarts. I'm losing my sanity here. I know that the issue is not the pointer, but the call to the function using the pointer. Using println & delay(500), in a new function inside the Manager I can do the following without issue (no restart):
- retrieve pointer from vector. All good.
- assign pointer from vector to a temporary pointer type to be able to refer to that pointer. All good
- calling the function in the object causes instant Arduino Hardware reset (not a single line will execute in the function that is called).
All this leads me to the conclusion that calling the function in the object is causing a problem. I rewrote a simplified version of the code below, and it executes well on this website (please see: https://godbolt.org/z/G3x556), but on the Arduino it crashes.
What can I do to understand why the object crashes the program? how can I validate that the object is OK prior to calling the function? Why does the call to the function in an object that should be alive crashes the system? why does the call work in the function which stored it in the vector, but not in a different function? How can I answer these questions. I have hit a limit on ideas. Thank you for your time!
My code simplified:
#include <iostream>
//#include <ArduinoSTL.h> //commented out to work on website
#include <vector>
//base class is used to be able to push everything into a std::vector
//in ArduinoSTL lib.
class Base
{
public:
virtual void continueExecution()
{ std::cout << "Base" << std::endl; }
// a polymorphic class MUST have a virtual destructor
virtual ~Base(){};
};
//lots of these classes will exist one day if I keep at this grind
class Derived : public Base
{
public:
Derived()
{
std::cout<< "Derived constructor" << std::endl;
}
void startExecution()
{
std::cout << "Derived object, start function"<< std::endl;
//start work
}
void continueExecution()
{
//continue when time has eleapsed
std::cout << "Derived continueExectution " << std::endl;
}
};
class Manager
{
public:
void beginExecutingDerivedObject()
{
//derived object
Derived derivedObj;
derivedObj.startExecution();
myVector.push_back(&derivedObj);
//if I run the line that crashes the code below this
//comment, all is OK. But that is not where it is needed.
myVector.back()->continueExecution();
}
void finishExecutionOfDerivedObject()
{
//CODE CRASH HERE. The moment the function is called, a reset
//occurs.
myVector.back()->continueExecution();
//any code here may appear on the console, but it's just a
//memory dump. By this point, the Arduino has thrown up it's arms.
}
private:
//create vector
std::vector<Base*> myVector;
};
//main is actually the arduino loop()
int main()
{
//this manager class is in the sketch global space
Manager manager;
//this is called by a function call in the loop()
manager.beginExecutingDerivedObject();
//this is also called by a function call in the loop()
manager.finishExecutionOfDerivedObject();
}