-1
QByteArray array;
union {
   char bytes[sizeof(float)];
   float value;
} myFloat;

for (int i = 0; i < 10; i++) {
    myFloat.value = 2.3 + i;
    array.append(myFloat.bytes);
    qDebug() << array.length(); //9, 18, 27, etc, instead of 4, 8, 12, etc?
}

Hey, I'm trying to construct a QByteArray to store and send via TCP at a later stage, via QTcpSocket::write(QByteArray);. However, the length increase of the array was not what I expected, and when I send it via Tcp, my readHandler seems to start reading gibberish after the first float. This seems to be solved by using another append function array.append(float.bytes, sizeof(float));. Does anyone know:

  • What went wrong in the first place? Why does adding a 4 byte char result in a 9 bytes longer QByteArray? Has it to do with the \o's being added?
  • Will array.append(float.bytes, sizeof(float)); method work? Meaning, if I send the array, will I send 10*4 bytes of raw float values?
Daan R
  • 58
  • 9
  • 5
    How would `QByteArray::append` know that you want to append exactly 4 bytes? It expects a nul-terminated c-string, not a chunk of binary bytes. – tkausl Sep 17 '17 at 01:54
  • Good point. I didn't think about that. So I was basically reading random memory to the QByteArray? And does that imply that `QByteArray::append(char*, len)` will read the chunk of binary bytes correctly? – Daan R Sep 17 '17 at 02:37
  • 2
    `QByteArray &QByteArray::append(const char *str, int len)` is what you need. – Daniel Sep 17 '17 at 02:58

1 Answers1

0

The append() overload you (unintentionally) picked treats the passed argument as a zero-terminated string. Obviously, the float value seems to contain a zero byte at some point so the append() function eventually stops reading.

To append binary data, I'd use QByteArray::fromRawData() to obtain a QByteArray and then append it:

float f = 3.14;
QByteArray a = QByteArray::fromRawData(&f, sizeof(f));
QByteArray b;
b += a;

This makes your intention clear and it avoids the union trick, which is undefined behaviour anyway.

Kamajii
  • 1,826
  • 9
  • 21
  • 1
    union tricks are valid as long as it's `char`. It's only `union { int i; float f; }` that's UB. – o11c Sep 17 '17 at 05:37