Problem with atributte shared_ptr in class base and derived

109 views Asked by At

Given something function like this:

void process() {
  std::shared_ptr<Receiver> receiver(std::make_shared<Receiver>());

  Command *cmd1 = new InfoCMD(receiver,10);
  cmd->Execute();
  delete cmd;
  DELAY_MS(1000);
  Command *cmd2 = new InfoCMD(ble,20);
  cmd2->Execute();
  DELAY_MS(1000);
  delete cmd2;
}

Being the base class BLECommand like this:

class Command {

protected:
    std::shared_ptr<Receiver> pReceiver_;

public:
    Command(std::shared_ptr<Receiver> receiver) : pReceiver_(receiver) {}
    virtual ~Command() {}
    virtual void Execute() const = 0;
};

I have a error due a double delete BLEReceiver objetct (ble) and I don't have idea because happens that. The shared_ptr class should avoid this.

For debug this issue, I have put a print in the destructor of BLEReceiver class, and this is the output on the device console:

W (9932) Receiver: delete receiver
W (10872) Receiver: delete receiver
CORRUPT HEAP: multi_heap.c:172 detected at 0x3ffbddcc

abort() was called at PC 0x4008d873 on core 0
Setting breakpoint at 0x40089a0a and returning...

Any idea to solve this problem? Thanks in advance.

Edit:

The declaration of base class is this:

class InfoCMD : public Command { 
   private:
   uint32_t info;
   public:
   InfoBLECMD(std::shared_ptr<BLEReceiver>  receiver,uint32_t info) :    
              Command(receiver),                                                                                         
              info(info){};                                                                                         
   ~InfoCMD(){}
   void Execute() const;
   };

And the definition is something like this:

void InfoCMD::Execute() const{

  this->pReceiver_->setData(this->info);

  this->pReceiver_->SendData();

}
1

There are 1 answers

2
Zig Razor On

Ok your piece of code does not highlight the error, in fact I try to reproduce that with this code:

// Example program

#include <iostream>
#include <memory>
#include <unistd.h>

using namespace std;

class BLEReceiver {
    public:
        BLEReceiver(){i =1;}
        virtual ~BLEReceiver(){std::cout << "destroyed" << std::endl;}
    private:
    int i;
};


class BLECommand {

protected:
    std::shared_ptr<BLEReceiver> pBLEReceiver_;

public:
    BLECommand(std::shared_ptr<BLEReceiver> receiver) : pBLEReceiver_(receiver) {}
    virtual ~BLECommand() {}
    virtual void Execute() const {std::cout << "execute"<<std::endl;};
};

int main()
{
    std::shared_ptr<BLEReceiver> ble(std::make_shared<BLEReceiver>());

    BLECommand *idreq = new BLECommand(ble);

    idreq->Execute();
    delete idreq;
    sleep(1);
    BLECommand *versionreq = new BLECommand(ble);
    versionreq->Execute();
    sleep(1);
    delete versionreq;
}

And it works perfectly with output :

execute
execute
destoyed

You can try it on C++ Shell.

So the problem in your code is other piece of code. Probably you use the shared_ptr in a wrong way, let the memory used by this pointer is destroyed before the call of delete.