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.

Answer from Nikolai Fetissov on Stack Overflow
Top answer
1 of 11
404

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.

2 of 11
165

(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 alignment requirement.
    E.g., on many systems, an int should start at an address divisible by 4 and a 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 strictest alignment requirement of any of its members, by padding at end.
    E.g., on many systems, if struct's largest member is int then by divisible by 4, if 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.

Address in memory (for struct)

Empty space:

  • Empty space between 2 structs could be used by non-struct variables that could fit in.
    e.g in test_struct_address() below, the variable x resides between adjacent struct g and h.
    No matter whether x is declared, h's address won't change, x just reused the empty space that g wasted.
    Similar case for y.

Example

(for 64 bit system)

memory_align.c:

/**
 * Memory align & padding - for struct.
 * compile: gcc memory_align.c
 * execute: ./a.out
 */ 
#include <stdio.h>

// size is 8, 4 + 1, then round to multiple of 4 (int's size),
struct stu_a {
    int i;
    char c;
};

// size is 16, 8 + 1, then round to multiple of 8 (long's size),
struct stu_b {
    long l;
    char c;
};

// size is 24, l need padding by 4 before it, then round to multiple of 8 (long's size),
struct stu_c {
    int i;
    long l;
    char c;
};

// size is 16, 8 + 4 + 1, then round to multiple of 8 (long's size),
struct stu_d {
    long l;
    int i;
    char c;
};

// size is 16, 8 + 4 + 1, then round to multiple of 8 (double's size),
struct stu_e {
    double d;
    int i;
    char c;
};

// size is 24, d need align to 8, then round to multiple of 8 (double's size),
struct stu_f {
    int i;
    double d;
    char c;
};

// size is 4,
struct stu_g {
    int i;
};

// size is 8,
struct stu_h {
    long l;
};

// test - padding within a single struct,
int test_struct_padding() {
    printf("%s: %ld\n", "stu_a", sizeof(struct stu_a));
    printf("%s: %ld\n", "stu_b", sizeof(struct stu_b));
    printf("%s: %ld\n", "stu_c", sizeof(struct stu_c));
    printf("%s: %ld\n", "stu_d", sizeof(struct stu_d));
    printf("%s: %ld\n", "stu_e", sizeof(struct stu_e));
    printf("%s: %ld\n", "stu_f", sizeof(struct stu_f));

    printf("%s: %ld\n", "stu_g", sizeof(struct stu_g));
    printf("%s: %ld\n", "stu_h", sizeof(struct stu_h));

    return 0;
}

// test - address of struct,
int test_struct_address() {
    printf("%s: %ld\n", "stu_g", sizeof(struct stu_g));
    printf("%s: %ld\n", "stu_h", sizeof(struct stu_h));
    printf("%s: %ld\n", "stu_f", sizeof(struct stu_f));

    struct stu_g g;
    struct stu_h h;
    struct stu_f f1;
    struct stu_f f2;
    int x = 1;
    long y = 1;

    printf("address of %s: %p\n", "g", &g);
    printf("address of %s: %p\n", "h", &h);
    printf("address of %s: %p\n", "f1", &f1);
    printf("address of %s: %p\n", "f2", &f2);
    printf("address of %s: %p\n", "x", &x);
    printf("address of %s: %p\n", "y", &y);

    // g is only 4 bytes itself, but distance to next struct is 16 bytes(on 64 bit system) or 8 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "g", "h", (long)(&h) - (long)(&g));

    // h is only 8 bytes itself, but distance to next struct is 16 bytes(on 64 bit system) or 8 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "h", "f1", (long)(&f1) - (long)(&h));

    // f1 is only 24 bytes itself, but distance to next struct is 32 bytes(on 64 bit system) or 24 bytes(on 32 bit system),
    printf("space between %s and %s: %ld\n", "f1", "f2", (long)(&f2) - (long)(&f1));

    // x is not a struct, and it reuse those empty space between struts, which exists due to padding, e.g between g & h,
    printf("space between %s and %s: %ld\n", "x", "f2", (long)(&x) - (long)(&f2));
    printf("space between %s and %s: %ld\n", "g", "x", (long)(&x) - (long)(&g));

    // y is not a struct, and it reuse those empty space between struts, which exists due to padding, e.g between h & f1,
    printf("space between %s and %s: %ld\n", "x", "y", (long)(&y) - (long)(&x));
    printf("space between %s and %s: %ld\n", "h", "y", (long)(&y) - (long)(&h));

    return 0;
}

int main(int argc, char * argv[]) {
    test_struct_padding();
    // test_struct_address();

    return 0;
}

Execution result - test_struct_padding():

stu_a: 8
stu_b: 16
stu_c: 24
stu_d: 16
stu_e: 16
stu_f: 24
stu_g: 4
stu_h: 8

Execution result - test_struct_address():

stu_g: 4
stu_h: 8
stu_f: 24
address of g: 0x7fffd63a95d0  // struct variable - address dividable by 16,
address of h: 0x7fffd63a95e0  // struct variable - address dividable by 16,
address of f1: 0x7fffd63a95f0 // struct variable - address dividable by 16,
address of f2: 0x7fffd63a9610 // struct variable - address dividable by 16,
address of x: 0x7fffd63a95dc  // non-struct variable - resides within the empty space between struct variable g & h.
address of y: 0x7fffd63a95e8  // non-struct variable - resides within the empty space between struct variable h & f1.
space between g and h: 16
space between h and f1: 16
space between f1 and f2: 32
space between x and f2: -52
space between g and x: 12
space between x and y: 12
space between h and y: 8

Thus address start for each variable is g:d0 x:dc h:e0 y:e8

🌐
TutorialsPoint
tutorialspoint.com › cprogramming › c_structure_padding_and_packing.htm
Structure Padding and Packing in C
Structure packing, on the other hand, is a mechanism for minimizing the effect of padding, thereby trying and reduce wasted memory space.
🌐
SkillVertex
skillvertex.com › blog › structure-member-alignment-padding-and-data-packing
Structure Member Alignment, Padding And Data Packing
May 10, 2024 - Padding is the technique used by compilers to add extra bytes to structures for alignment purposes, optimizing memory access at the cost of increased memory usage. Data Packing, on the other hand, involves adjusting the alignment and padding ...
🌐
Catb
catb.org › esr › structure-packing
The Lost Art of Structure Packing
Note also that, as with normal structure padding, the padding bits are not guaranteed to be zero; C99 mentions this. Note that the base type of a bit field is interpreted for signedness but not necessarily for size. It is up to implementors whether "short flip:1" or "long flip:1" are supported, and whether those base types change the size of the storage unit the field is packed into.
🌐
University at Buffalo
cse.buffalo.edu › ~eblanton › course › cse220-2020-2f › materials › 11-alignment.pdf pdf
CSE 220: Systems Programming Alignment, Padding, and Packing Ethan Blanton
The members of a structure are adjacent in memory. This is similar to scalars in an array. However, there are additional considerations regarding layout. The alignment of array members must be preserved! Padding is inserted between values to bring them into alignment.
🌐
FIRMWARE DEVELOPER
firmcodes.com › home › structure padding and packing in c example
structure padding and packing in c example-Firmware Developer
August 5, 2015 - Packing, on the other hand prevents compiler from doing padding means remove the unallocated space allocated by structure. In case of Linux we use __attribute__((__packed__)) to pack structure.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › structure-member-alignment-padding-and-data-packing
Structure Member Alignment, Padding and Data Packing - GeeksforGeeks
Structure padding is the addition of some empty bytes of memory in the structure to naturally align the data members in the memory. It is done to minimize the CPU read cycles to retrieve different data members in the structure.
Published   July 29, 2025
Find elsewhere
🌐
House-master-assist
house-master-assist.com › article › what-is-the-difference-between-padding-and-structure-packing
What is the difference between padding and structure packing?
Before each individual member, ... and packing are just two aspects of the same thing: packing or alignment is the size to which each member is rounded off padding is the extra space added to match the alignment...
🌐
DevTut
devtut.github.io › c › structure-padding-and-packing.html
C - Structure Padding and Packing
Depending on the CPU architecture ... between members or at the end of the structure, but not at the beginning. Packing overrides the default padding....
🌐
Wikipedia
en.wikipedia.org › wiki › Data_structure_alignment
Data structure alignment - Wikipedia
February 10, 2026 - For example, on a 32-bit machine, a data structure containing a 16-bit value followed by a 32-bit value could have 16 bits of padding between the 16-bit value and the 32-bit value to align the 32-bit value on a 32-bit boundary. Alternatively, one can pack the structure, omitting the padding, which may lead to slower access, but saves 16 bits of memory.
🌐
Rip Tutorial
riptutorial.com › structure padding and packing
C Language Tutorial => Structure Padding and Packing
Depending on the CPU architecture ... between members or at the end of the structure, but not at the beginning. Packing overrides the default padding....
🌐
UW Computer Sciences
pages.cs.wisc.edu › ~csxpeng › dev › c++ › concepts › data_alignment.html
Structure Member Alignment, Padding and Data Packing - GeeksforGeeks | GeeksforGeeks
January 1, 2011 - Since char can be on any byte boundary ... in between short int and char, on total they occupy 3 bytes. The next member is int. If the int is allocated immediately, it will start at an odd byte boundary. We need 1 byte padding after the char member to make the address of next int member is 4 byte aligned. On total, the structb_t requires 2 + 1 + 1 (padding) + 4 = 8 bytes. structure C – Every ...
🌐
Programming-books
programming-books.io › essential › c › structure-padding-and-packing-5652547af4f34cf5a783864b5fd4d5e5
Structure Padding and Packing - Essential Programming Books
Depending on the CPU architecture ... between members or at the end of the structure, but not at the beginning. Packing overrides the default padding....
🌐
Matheusmello
matheusmello.io › posts › c-structure-padding-and-packing
Structure padding and packing
Padding adds extra bytes within a structure to align members according to memory boundaries, enhancing performance at the expense of larger memory usage. Packing reduces or removes padding to minimize memory consumption but may result in slower memory access due to inefficient alignment...
🌐
Scaler
scaler.com › home › topics › what is structure padding in c?
What is Structure Padding in C? - Scaler Topics
May 30, 2024 - If this set of data will be read by different software, or if a new field is added to the structure, it may be sensible to pack the struct to make the data structure easy and clear. Structure padding in C is a very important and useful concept but sometimes it may be less secure as the values stored in the padding spaces between ...
🌐
Harsh's den
harshwsingh.hashnode.dev › packing-and-padding-in-c
Structure padding in C - Harsh's den
December 11, 2022 - Well, take a guess, go on, and take your time. The size of different data types depends on the type of processor you have. As per modern 32/64 bit processors, the size of int is 4 Bytes, Char is 1 Byte & Float is 4 Bytes. Let’s calculate the size of our student structure : 4B + (1B x 10) + 4B = 18 Bytes · Well, wrong! There exists this thing called “Structure Padding” which pads the memory if it’s not aligned as per the datatype’s need due to which the actual size of our structure would be: 4B + (1B x 10) + 2B (padding) + 4B = 20 Bytes
🌐
Equestionanswers
equestionanswers.com › c › struct-pack-padding.php
What is packing in structure and how compiler adds padding between member elements?
Packing is an option in compiler to define how the members of a structure will be aligned in memory. It is defined via pre-processor #pragma pack( ). For 32bit compiler pack(4) is default and similarly for 64bit pack(8) is default. Now we are instructing compiler to align members in 4byte memory ...
🌐
Embedclogic
embedclogic.com › structure-packing-alignment-padding-in-c
Structure Packing, Alignment and Padding
December 31, 2022 - Padding is the process of insertion of reserve bytes to fill the gap between the structure member cause due to alignment. ... .As we can see padding does the lots of memory waste whether it increases the performance.Some of the processor does ...
🌐
Google Sites
sites.google.com › site › jdsarodeprogramming › some-problems-and-links › structure-padding-and-packing
jayprogramming - Structure Padding and Packing
Note also that, as with normal structure padding, the padding bits are not guaranteed to be zero; C99 mentions this. Note that the base type of a bit field is interpreted for signedness but not necessarily for size. It is up to implementors whether "short flip:1" or "long flip:1" are supported, and whether those base types change the size of the storage unit the field is packed ...