QByteArray being corrupted in a custom class
-
Hi all. I am writing a Qt app and I have made a custom class for serializing/deserializing a message to be sent to the device.
class Message { public: enum MessageType { ACK = 0x01, COMMAND_1 = 0x0c, COMMAND_2 = 0x0e }; MessageType type() const; int sequence() const; QByteArray data() const; QByteArray encode(); QByteArray encode(int sequenceNumber); static quint32 payloadLength(const QByteArray &data); private: MessageType m_type; int m_sequence; QByteArray m_data; };
Now I have to encode the message when sending it, so I store these
Message
's in a QQueue. But when I dequeue the message to encode it, QByteArray is magically corrupted! It loses all of the data but all of the other member variables are fine. And interestingly, if I don't initializem_data
but rather add data to it withappend()
, the corruption goes away!I have been pulling my hair out for the past week and I have no idea why this happens, any ideas would be greatly appreciated!
-
@TheVancedGamer No, that's a regular copy constructor - which only increments a reference count as
QByteArray
is implicitly shared.The symptom you describe makes me think that the original
QByteArray
you created and eventually passed to theMessage
constructor doesn't own its' buffer - that is, was created with something likeQByteArray::fromRawData
or the like. -
@Bonnie I mean, I just initialized it with the variable as in the constructor like this:
Message::Message(MessageType type, int sequenceNumber, QByteArray payload): m_type(type), m_sequence(sequenceNumber), m_data(payload) { //m_data.append(payload); }
This probably did the move-constructor?
-
@TheVancedGamer No, that's a regular copy constructor - which only increments a reference count as
QByteArray
is implicitly shared.The symptom you describe makes me think that the original
QByteArray
you created and eventually passed to theMessage
constructor doesn't own its' buffer - that is, was created with something likeQByteArray::fromRawData
or the like. -
@TheVancedGamer I think I was wrong. You probably need to init it with a reference variable to call the move-constructor.
@IgKh Right, this makes sense. In that case, deep copy byappend()
is the correct way. -
@TheVancedGamer
QByteArray
uses implicit sharing, with copy-on-write. Your append-trick is one option to force a copy. It's better, however, to make the c'tor argument const-ref, i.e.const QByteArray &payload
. -