Why is the size of this struct 24?
The alignment of uint16_t
is only 2, hence the offsets are:
#pragma pack(push,4)struct MyStruct{ uint32_t i1; /* offset=0 size=4 */ uint32_t i2; /* offset=4 size=4 */ uint16_t s1; /* offset=8 size=2 */ unsigned char c[8]; /* offset=10 size=8 */ uint16_t s2; /* offset=18 size=2 */ uint16_t s3; /* offset=20 size=2 */ /* offset=22 padding=2 (needed to align MyStruct) */} ; // total size is 24
EditThe padding at the end is necessary to ensure that all elements of
MyStruct A[10]; // orMyStruct*B = new MyStruct[10];
are aligned appropriately. This requires that sizeof(MyStruct)
is a multiple of alignof(MyStruct)
. Here, sizeof(MyStruct)
=6*alignof(MyStruct)
.
Any struct
/class
type is always padded to the next multiple of its alignment.
In addition to Walter's answer, consider catching this fish yourself. All you need is the printf function and simple arithmetic:
struct MyStruct ms; printf("sizeof(ms): %zd\n", sizeof(ms)); printf("i1\t%td\n", (uint8_t*)&ms.i1 - (uint8_t*)&ms); printf("i2\t%td\n", (uint8_t*)&ms.i2 - (uint8_t*)&ms); printf("s1\t%td\n", (uint8_t*)&ms.s1 - (uint8_t*)&ms); printf("c \t%td\n", (uint8_t*)&ms.c - (uint8_t*)&ms); printf("s2\t%td\n", (uint8_t*)&ms.s2 - (uint8_t*)&ms); printf("s3\t%td\n", (uint8_t*)&ms.s3 - (uint8_t*)&ms);
(%zd
is for printing size_t
, %td
for printing ptrdiff_t
. A plain %d
will probably work just fine on most systems.)
Output:
sizeof(ms): 24i1 0i2 4s1 8c 10s2 18s3 20
4 4 2 8 2 2 - will be packed as:
4 4 4 8 2 2 - the last two are combined together in 4 bytes. the third item needs padding, the last and pre last do not.