Reputation: 18228
I have a structure of which I want to calculate its size:
#pragma pack(push,4)
struct MyStruct
{
uint32_t i1; /* size=4, offset=0. */
uint32_t i2; /* size =4 offset =4 */
uint16_t s1; /* size =2 offset=8 */
unsigned char c[8]; /* size=8 offset=12*/
uint16_t s2; /* size=2 offset=20. */
uint16_t s3; /* size=2 offset=24. */
} ; // total size is 26
static_assert(sizeof(MyStruct) == 24, "size of MyStruct incorrect");
#pragma pack(pop)
The static assert shows that the size is 24, but my calculation shows that it should be 26.
Why is the size 24?
I am working on windows 7, 32 bit application using visual studio 2012
Upvotes: 20
Views: 2632
Reputation: 215350
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): 24
i1 0
i2 4
s1 8
c 10
s2 18
s3 20
Upvotes: 22
Reputation: 45484
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
Edit The padding at the end is necessary to ensure that all elements of
MyStruct A[10]; // or
MyStruct*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.
Upvotes: 26
Reputation: 135
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.
Upvotes: -6