xQueue with pointer Object

i have tryed a lot and found some solutions for my Problems, but one is still driving me crazy.

I use the ESP32 with both cores.
I want to transmit a Queue between both.

class QueueMessage_t{
  private:
  public:
    uint8_t _Function = 0;
    uint16_t _ObjectIdentifier = 0;
    uint16_t _Propertie = 0;
    uint8_t _NMTCode = 0;
    uint8_t _NMTState = 0;
    uint8_t _SYNCCode = 0;
    bool _Acknowledge = false;
    DataBytes_t _DataBytes; 
};

class DataBytes_t{
    private:
        std::vector<uint8_t> *_DataBytes;
    public:
        void push_back(uint8_t Data){
            _DataBytes->push_back(Data);
        }
        int size(){
            return _DataBytes->size();
        }
        uint8_t & operator[](const int Index){
            return (uint8_t&)_DataBytes->operator[](Index);
        }
        DataBytes_t(){_DataBytes = new std::vector<uint8_t>;}
        ~DataBytes_t(){
             if(_DataBytes != nullptr){
                //_DataBytes->clear();
                //delete _DataBytes; 
                //_DataBytes = nullptr; 
            }     
        }
        DataBytes_t(const DataBytes_t &Copy){
            _DataBytes = new std::vector<uint8_t>;
            int size = Copy._DataBytes->size();
            if(size > 0){
                for(int a = 0; a < size; a++){
                    uint8_t buffer = Copy._DataBytes->at(a);
                    _DataBytes->push_back(buffer);
                }
            } 
        }
        void clear(){
            if(_DataBytes != nullptr){
                _DataBytes->clear();
            }
        }
};

//Core 1 cpp
void EnOceanClass::Reveive_Queue(){
QueueMessage_t Device_QueueMessage;
if(xQueueReceive(Device_Queue, &Device_QueueMessage ,pdMS_TO_TICKS(10))){
do my stuff here
and Transmit_Queue();
}

}

bool EnOceanClass::Transmit_Queue(QueueMessage_t CANBus_QueueMessage){
if(xQueueSend(CANBus_Queue, &CANBus_QueueMessage, pdMS_TO_TICKS(100)) !=pdPASS){
return false;
}
return true;
//here it leave the function. and the CANBus_QueueMessage will be delete and the deconstruktor
will be called
}

//Core0 cpp
void CANBusClass::Receive_Queue(){
QueueMessage_t CANBus_QueueMessage;
if(xQueueReceive(CANBus_Queue, &CANBus_QueueMessage, pdMS_TO_TICKS(10))){
do my stuff here
and Transmit_Queue();
}

}

bool CANBusClass::Transmit_Queue(QueueMessage_t Device_QueueMessage){
if(xQueueSend(Device_Queue, &Device_QueueMessage, pdMS_TO_TICKS(100)) != pdPASS){
return false;
}
return true;
//here it leave the function. and the Device_QueueMessagewill be delete and the
deconstruktor will be called
}

declaration of the Queue Core1, ( Queue for Core 0 the same (different name))
QueueHandle_t Device_Queue = xQueueCreate(16, sizeof(QueueMessage_t));

Now the Problem

Core0 sends a Queue to Core1
Core1 receives the Queue and work with it.
Core0 ends the function where the CANBus_QueueMessage (QueueMessage_t) and calls the Deconstructor → the Pointer to the vector in _DataBytes will be deleted! And an Exception will be thrown out.
For this i searched for the xQueueSend documentation.
xQueueSend(CANBus_Queue, &CANBus_QueueMessage, pdMS_TO_TICKS(100)) != pdPASS)

And this does a Deep Copy and copy the adress of the Pointer to the Queue Storage Area.
At this Point i wantet do create my own Copy Constructor. It worked fine. But the XQueueSend does not use it. So when Core 0 delete the QueueMessage-> the Pointer Adress in the Queue Storage Area for _DataBytes will also be deleted.

My Question: Is there a Overload function/operator for the XQueueSend which i did not found? That it use the Copy Construktor/Function of my Class .

I tested a lot and dont know what is important or not.
So if i forget something i will submit it later.

Thanks for Help :slight_smile:

RTOS is a C library. It has no plan of C++ copy constructors and destructors. It will copy your data around with plain old memcpy().

So you have to switch to a simpler data type, either a basic type like int or a C struct.

If you have data of variable length like an array, use a pointer to the array within the C struct. The array will not be copied but the pointer will be. So if you take care not to double release it or to use it after release, you should be safe.

1 Like

Thanks for replying.

Yes this is the problem. The Pointer Adress wil be deleted befor the other core can copie the data by it self.
Workaround now: it works with delay(); But i will try to include a Semaphore.

Thanks.