Ben Sla
Ben Sla

Reputation: 41

A byte is ignored by the computer when casting a char[] to a struct in C++

I'm writing a client-server program where the client-side is written in C++ and the server-side is in Python.

A stream of bytes is sent from the server-side and received to a char[] buffer and then converted with reinterpret_cast to an appropriate struct.

char response_buffer[7];
recv(sock, response_buffer, 7, 0);
s_response* response = reinterpret_cast<s_response*>(response_buffer);
cout << response -> code << endl;

where the struct is defined this way:

typedef struct {
    unsigned char version;
    unsigned short code;
    unsigned int payload_size;
} s_response;

But instead of version (1 byte) getting the value in response_buffer[0], and code getting response_buffer[1] and response_buffer[2] (two bytes), code ends up getting the value in response_buffer[2] and response_buffer[3], and payload_size getting response_buffer[4] to response_buffer[6], and thus, the value response_buffer[1] is not inserted into any of the struct's attributes and the result is a whole mess.

At first, I thought that it's due to endianness, but when I send the values 2, 2001, and 13821, for example, from the server-side, the following values are in response_buffer:

0. 00000010
1. 11101001
2. 00000011
3. 11111101
4. 00110101
5. 00000000
6. 00000000

This is what I expect to get and in the right order. But when I print out response->code I get the value 64771 which is 11111101 00000011 (2 and 3 in the above list) instead of 2001 which is 00000011 11101001 (1 and 2 in the list). Meaning, when I'm casting the char* to the s_response*, the byte in position 1 in the response_buffer is just ignored, and the values from there-on are one-byte shifted from the correct order.

Any idea what am I doing wrong?

Upvotes: 1

Views: 66

Answers (1)

Ben Sla
Ben Sla

Reputation: 41

As written in the comments, it was struct padding that made the problem. It can be solved by adding #pragmas as shown below

#pragma pack(push,1)
typedef struct {
    unsigned char version;
    unsigned short code;
    unsigned int payload_size;
} s_response;
#pragma pack(pop)

Upvotes: 2

Related Questions