Structure Padding and Packing

Structure Padding and Packing

Consider:

struct mystruct_A
{
   char a;
   int b;
   char c;
} x;

struct mystruct_B
{
   int b;
   char a;
} y;

The sizes of the structures are 12 and 8 respectively.

Are these structures padded or packed?

When does padding or packing take place?

6

11 Answers

Padding aligns structure members to "natural" address boundaries - say, int members would have offsets, which are mod(4) == 0 on 32-bit platform. Padding is on by default. It inserts the following "gaps" into your first structure:

struct mystruct_A {
    char a;
    char gap_0[3]; /* inserted by compiler: for alignment of b */
    int b;
    char c;
    char gap_1[3]; /* -"-: for alignment of the whole struct in an array */
} x;

Packing, on the other hand prevents compiler from doing padding - this has to be explicitly requested - under GCC it's __attribute__((__packed__)), so the following:

struct __attribute__((__packed__)) mystruct_A {
    char a;
    int b;
    char c;
};

would produce structure of size 6 on a 32-bit architecture.

A note though - unaligned memory access is slower on architectures that allow it (like x86 and amd64), and is explicitly prohibited on strict alignment architectures like SPARC.

13

(The above answers explained the reason quite clearly, but seems not totally clear about the size of padding, so, I will add an answer according to what I learned from The Lost Art of Structure Packing, it has evolved to not limit to C, but also applicable to Go, Rust.)


Memory align (for struct)

Rules:

  • Before each individual member, there will be padding so that to make it start at an address that is divisible by its size.
    e.g on 64 bit system,int should start at address divisible by 4, and long by 8, short by 2.
  • char and char[] are special, could be any memory address, so they don't need padding before them.
  • For struct, other than the alignment need for each individual member, the size of whole struct itself will be aligned to a size divisible by size of largest individual member, by padding at end.
    e.g if struct's largest member is long then divisible by 8, int then by 4, short then by 2.

Order of member:

  • The order of member might affect actual size of struct, so take that in mind. e.g the stu_c and stu_d from example below have the same members, but in different order, and result in different size for the 2 structs.

Alexander Ross
Author

Alexander Ross

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.