How to Use struct Alignment and Padding in C

Jinku Hu Feb 02, 2024
  1. Understand the Basics of Alignment and Padding in C
  2. Use Member Reordering Technique to Save Space in Objects in C
How to Use struct Alignment and Padding in C

This article will explain several methods of how to use struct alignment and padding in C.

Understand the Basics of Alignment and Padding in C

All objects in memory are represented as the primary data types like: char, short, int, long, pointer etc. These data types have their corresponding size in memory. On most contemporary 64-bit desktop processors, the sizes are 1 byte for a char, 2 bytes for a short, 4 bytes for an int, 8 bytes for a pointer, and so on. Note that these are not guaranteed sizes (except for char), but one can retrieve the object’s size using the sizeof operator. Now, alignment is the method that compilers employ to place variables in the memory, implying that each basic data type is stored at the address divisible by the corresponding size.

Usually, alignment is utilized to access data objects faster and efficiently. Alignment forces continuously declared different data types to include some spacing between their addresses. Namely, if we declare a structure st1 with one pointer and a char as shown in the following example, it will take up 16 bytes in total. Mind though, a single pointer takes 8 bytes and a char takes one byte, so one would think the st1 struct must occupy 9 bytes. But it behaves as if all members are aligned to the largest member’s size (i.e. 8 bytes). st2 struct demonstrates a similar structure that occupies the same amount of memory, except that it has an array of 7 char members.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[]) {
  typedef struct {
    char *p;
    char c2;
  } st1;

  typedef struct {
    char *p;
    char c2;
    char padding[7];
  } st2;

  printf("sizeof st1 = %zu\n", sizeof(st1));
  printf("sizeof st2 = %zu\n", sizeof(st2));

  exit(EXIT_SUCCESS);
}

Output:

sizeof st1 = 16
sizeof st2 = 16

Use Member Reordering Technique to Save Space in Objects in C

The previous example demonstrates that there’s some waste of memory when structures include different types and don’t fill up the alignment boundaries. Although, there are some cases where it might be possible to reorder structure members and save extra space.

The next example code defines foo1 struct that has the largest member (char *) in the middle and foo2 with the same member as the first one. The sizes of these two objects are different - 24 bytes and 16 bytes. This has to do with the ordering of the data members. In the foo1 structure, p needs to be aligned at the address that is divisible by 8, so the int and short before it will occupy 8 bytes in total and two chars after it will occupy the 8 bytes as well. Although, if we move p to the first place, the following members will squeeze into the 8 bytes and the alignment rule is satisfied as well. Thus, foo2’s size totals 16 bytes and it’s called to be packed struct. Note that the gcc compiler has the special __attribute__ ((packed)) specifier that can force even unordered struct members to be packed.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[]) {
  typedef struct {
    int n1;
    short s1;
    char *p;
    char c1;
    char c2;
  } foo1;

  typedef struct {
    char *p;
    int n1;
    short s1;
    char c1;
    char c2;
  } foo2;

  typedef struct {
    int n1;
    short s1;
    char *p;
    char c1;
    char c2;
  } __attribute__((packed)) foo3;

  printf("sizeof foo1 = %zu\n", sizeof(foo1));
  printf("sizeof foo2 = %zu\n", sizeof(foo2));
  printf("sizeof foo3 = %zu\n", sizeof(foo3));

  exit(EXIT_SUCCESS);
}

Output:

sizeof foo1 = 24
sizeof foo2 = 16
sizeof foo3 = 16
Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Related Article - C Struct