I studied The Lost Art of Structure Packing, but the following experiment confused me.
Here is the code:
#include <stdio.h>
int main(int argc, char **argv)
{
struct a_t {
char aa;
};
struct b_t {
int bb;
int bbb;
};
struct c_t {
struct a_t parent_a;
struct b_t parent_b;
char cc;
};
struct c_t c;
printf("sizeof(a_t)=%d\n", sizeof(struct a_t));
printf("sizeof(b_t)=%d\n", sizeof(struct b_t));
printf("c address=%p\n", &c);
printf("c's parent_a=%p\n", &(c.parent_a));
printf("c's parent_b=%p\n", &(c.parent_b));
printf("c sizeof(a_t)=%p\n", (struct b_t *)(&c sizeof(struct a_t)));
return 0;
}
Here is output:
sizeof(a_t)=1
sizeof(b_t)=8
c address=0x7fff9bca7680
c's parent_a=0x7fff9bca7680
c's parent_b=0x7fff9bca7684
c sizeof(a_t)=0x7fff9bca7690
The last 3 lines in the output are surprises:
c's parent_a=0x7fff9bca7680
, this is expected. parent_a address equals to struct variable c's address.c's parent_b=0x7fff9bca7684
, this is a surprise, parent_b size is 8 bytes, how come its address is not multiple of 8?c sizeof(a_t)=0x7fff9bca7690
, this is a surprise, this is 16 bytes beyond c's address!struct a_t
is size 1 byte, I had expected it is 0x7fff9bca7681.
Could you shed light?
CodePudding user response:
Answer 2. c_t
only has to be 4-byte-aligned due to the size of its largest member.
Answer 3. Due to pointer math, &c
is a pointer to a c_t
which has size 16, so adding one to that pointer adds 16 bytes to the address.
The size of c_t
is 16 because a_t
is size 1, 3 bytes of padding to align b_t
, size of b_t is 8 (total 12), then char cc
is size 1, but needs 3 bytes of padding at the end (total 16) so if c_t
is used in an array it will still have all its members aligned on 4-byte boundaries (the size of the largest member).