Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

esp32 c++ pointer to object is lost?

I dont understand why this is not working… will try to explain the best I can:

in main I need an object of class Sim800Cls. Sim800Cls on the other hand, needs an object of class Prueba.
both Sim800Cls and Prueba need to use a software serial object, so both contains a private var that is a pointer to a softserial object.

So in main, I create a softserial object and a Sim800cls object. Then call Sim800Cls init() method passing it a pointer to the softserial.
in Sim800Cls.init(), it assigns the pointer to its private var, then calls init() method of Prueba, passing it that same pointer. And in Prueba.init(), it just assigns the pointer to its own private variable.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

in Sim800Cls.init(), just after calling init() of Prueba, I call a method of Prueba that uses the soft serial to check if it works. And it does.
But outside of that init(), it breaks. It seems as if Prueba looses the pointer to the softserial or something like that…
(the exception is thrown in sendCommand() method, at the line _GsmSerial->write(command.c_str());)

What is going on here? what am I doing wrong?

Main:

#include "Sim800Cls.h"
SoftwareSerial GsmSoftSerial;
Sim800Cls GsmSim800;     
   void setup() {
      ...
      GsmSoftSerial.begin(GSM_SOFT_SERIAL_BAUDS, SWSERIAL_8N1, GSM_SOFT_SERIAL_RX_PIN, GSM_SOFT_SERIAL_TX_PIN, false);
      while (!GsmSoftSerial) { ; }  // wait for serial port to connect.
      
      GsmSim800.init(&GsmSoftSerial);    //-> this runs ok
      GsmSim800.method1()                //-> this throws exception
      ...
   }

Sim800Cls.h:

   class Sim800Cls {
      private:
      protected:
         SoftwareSerial *_GsmSerial;
         PruebaCls *_MiPrueba;
   ...

Sim800Cls.cpp:

   void Sim800Cls::init(SoftwareSerial *GsmSoftSerial) {
      _GsmSerial = GsmSoftSerial;
      
      PruebaCls p;
      _MiPrueba = &p;
      _MiPrueba->init(GsmSoftSerial);
      delay(200);
      
      method1();    //-> this works
   }

   void Sim800Cls::method1() {
      _MiPrueba->test1();
   }

Prueba.h:

   class Prueba {
      private:
      protected:
         SoftwareSerial *_GsmSerial;
   ...

Prueba.cpp:

   void PruebaCls::init(SoftwareSerial *GsmSoftSerial) {
      _GsmSerial = GsmSoftSerial;
   }

   bool PruebaCls::test1() {
      std::string command, resp;
      command = "AT\r";
      sendCommand(command);
      resp = leeSerial();
      return true;
   }

   void PruebaCls::sendCommand(std::string &command) {
      Serial.print("[PruebaCls] in sendCommand() - sending command: "); Serial.println(command.c_str());
      _GsmSerial->write(command.c_str());    
      delay(50);
      Serial.println("[PruebaCls] in sendCommand() - command sent."); 
   }

>Solution :

PruebaCls p; is a local variable, let’s assme it’s on the stack (typically it will be, if it’s not in a register).

_MiPrueba = &p; refers to that variable.

As long as execution is inside Sim800Cls::init(SoftwareSerial *GsmSoftSerial), that will work, since the variable is still in scope.

Once you left the init() method, the local variable is destructed and the stack is overwritten by something else, thus calling method1() results in undefined behavior.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading