At first glance, you might think that the size of a struct is simply the sum of the sizes of its members. However, if you use the sizeof operator, you will often find that the result is larger than expected. This "extra" space is called Padding.
Modern CPUs (32-bit or 64-bit) do not read data from memory 1 byte at a time. Instead, they read memory in fixed-size chunks called Words (typically 4 or 8 bytes).
Processor performance is highest when data is "aligned." For example, a 4-byte int should ideally be stored at a memory address that is a multiple of 4. If an int starts at address 1 instead of address 0 or 4, the CPU might need to perform two memory fetches to get that one integer, and then shift/mask the bits to combine them. This is incredibly inefficient.
Consider the following structure. Let's assume a system where an int is 4 bytes and a char is 1 byte.
The Math: 1 + 4 + 1 = 6 bytes.
The Reality: sizeof(struct Database) will likely return 12 bytes.
Here is what happens inside the memory:
id_prefix takes 1 byte at Offset 0.int coming next. It needs to start at a multiple of 4. So, it inserts 3 bytes of padding (Offset 1, 2, and 3).id_number takes 4 bytes (Offset 4, 5, 6, 7).flag takes 1 byte at Offset 8.As mentioned above, padding isn't just between members; it's often at the end. The total size of a structure is always a multiple of the size of its largest member.
If your largest member is a double (8 bytes), the total size of the struct will be padded to a multiple of 8, even if the actual data only takes up 9 bytes (it will jump to 16).
You can significantly reduce the memory footprint of your program by simply changing the order of your structure members. A good rule of thumb is to sort members by size in descending order (largest types first).
| Inefficient Order (12 Bytes) | Efficient Order (8 Bytes) |
|---|---|
char a;int b;char c;(Creates two gaps of padding) |
int b;char a;char c;(a and c sit together; only 2 bytes of tail padding) |
In specific cases, like sending data over a network or writing to a specific binary file format, you might need the struct to have zero padding. You can force the compiler to stop padding using a preprocessor directive.
Warning: While packing saves memory, it makes code slower on some CPUs and can even cause a crash (Bus Error) on architectures like ARM if not handled carefully. Use it only when strictly necessary.
struct definition!