0

I have a 255 byte array containing some data

  • flag: 1 byte (unsigned char)
  • address: 4 bytes (unsigned int)
  • text: 13 bytes (char[13])

My union looks like this:

union {
  unsigned char buf[255];

  struct{
    unsigned char flag;
    unsigned int address;
    char text[13];
  } structure;
} the_union

I used the following code to treat a buffer of data as my union, and through the union I can access it using the struct. (buf was passed in as a function parameter)

the_union * ptr = (the_union*) buf;
char flag = ptr->structure.flag;
unsigned int address = ptr->structure.address;
char * text = (char*) ptr->structure.text;

While debugging, I noticed that while the values I got in the buffer matched the structure I was expecting, when I tried to access them in the union, it was incorrect.

In my buffer, I had the following bytes:

[0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, .... ]

The values I got from my structure though were the following:

  • flag = 0x00
  • address = 0x00010203
  • text = { 0x04, 0x05, 0x00, 0x00, ... }

I was expecting flag to be 0, address to be 0, and text to be {0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, ...}. It seems that the alignment is wrong during access.

What is the explanation for this?

timrau
  • 22,578
  • 4
  • 51
  • 64
9a3eedi
  • 696
  • 2
  • 7
  • 18
  • 1
    `unsigned char` is padded... – Sourav Ghosh Apr 30 '15 at 05:54
  • 1
    possible duplicate of [What is a "packed" structure in C?](http://stackoverflow.com/questions/5473189/what-is-a-packed-structure-in-c) – 2501 Apr 30 '15 at 05:54
  • Manually process and assign the buffer to the members. There is no reason not to. – 2501 Apr 30 '15 at 05:57
  • I see. I had the assumption that padding was inserted at the end, not in between fields. Interesting. – 9a3eedi Apr 30 '15 at 05:58
  • Try tail padding create a new struct field. UNUSED[(255-(13+1+sizeof(int)))] ; This could be too big cos structures often have holes in so an int in a structure is still memory aligned. There are settings in gcc's to warn about these holes. I once tried to algorithmise the packing of a data structure, I got close, but was still miles off reality – phil Apr 30 '15 at 06:11

1 Answers1

2

The issue is that with most processors the access to 4 byte and 8 byte data items must be made at addresses that are a multiple of 4 bytes and 8 bytes respectively. That means if an int is 4 bytes that it will need to be on a 4 byte boundary. The char is a single byte, so 3 padding bytes were needed to align the int. If you had doubles or were on a 64 bit machine you would likely find that doubles and ints were aligned on 8 byte boundaries.

Brad Budlong
  • 1,775
  • 11
  • 10