Bird
Raised Fist0
Embedded Cprogramming~10 mins

Struct packing and alignment in Embedded C - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Struct packing and alignment
Define struct with members
↓
Compiler checks each member's size
↓
Align members to their natural boundaries
↓
Add padding bytes if needed
↓
Calculate total struct size with alignment
↓
Optionally apply #pragma pack to remove padding
↓
Use packed struct with no padding
↓
Access members carefully to avoid misaligned access
The compiler arranges struct members in memory with padding to align them for efficient access, but packing can remove this padding.
Execution Sample
Embedded C
struct Example {
  char a;
  int b;
  char c;
};
Defines a struct with char, int, and char members to show how padding is added for alignment.
Execution Table
StepMemberOffset Before AlignmentAlignment NeededPadding AddedOffset After Alignment
1a (char)0100
2b (int)1434
3c (char)8108
4Total struct size94312
💡 Struct size aligned to 4 bytes boundary, padding added after 'a' and at end.
Variable Tracker
VariableStartAfter Step 1After Step 2After Step 3Final
OffsetN/A0 (a)4 (b)8 (c)12 (total size)
Padding bytesN/A0303 (end padding)
Key Moments - 3 Insights
Why is there padding after the first char 'a' before the int 'b'?
Because 'b' is an int and needs to be aligned to a 4-byte boundary, so 3 padding bytes are added after 'a' as shown in execution_table row 2.
Why is the total struct size 12 bytes, not 9?
The struct size must be a multiple of the largest alignment (4 bytes), so 3 padding bytes are added at the end to reach 12 bytes total, as in execution_table row 4.
What happens if we use #pragma pack(1) on this struct?
Padding is removed, so members are packed tightly without gaps, but this can cause slower or unsafe access on some systems.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the offset of member 'b' after alignment?
A1
B4
C3
D8
💡 Hint
Check the 'Offset After Alignment' column for member 'b' in execution_table row 2.
At which step is padding added after member 'a'?
AStep 1
BStep 3
CStep 2
DStep 4
💡 Hint
Look at the 'Padding Added' column in execution_table row 2.
If we apply #pragma pack(1), what happens to the total struct size?
AIt becomes 6 bytes
BIt stays 12 bytes
CIt becomes 16 bytes
DIt becomes 4 bytes
💡 Hint
Refer to key_moments answer about packing removing padding and total size.
Concept Snapshot
Struct packing aligns members to their natural boundaries.
Padding bytes are added between members to achieve alignment.
Total struct size is aligned to the largest member's alignment.
#pragma pack(1) removes padding but may cause misaligned access.
Use packing carefully in embedded systems.
Full Transcript
Struct packing and alignment means the compiler arranges struct members in memory so each member starts at an address suitable for its type. For example, an int usually needs to start at an address divisible by 4. If a smaller member like char comes before an int, the compiler adds padding bytes after the char to align the int properly. This padding makes access faster and safer. The total size of the struct is also rounded up to a multiple of the largest alignment to keep arrays of structs aligned. Using #pragma pack(1) tells the compiler to remove padding and pack members tightly, but this can cause slower or unsafe memory access on some systems. The example struct with char, int, char members shows padding added after the first char and at the end to reach 12 bytes total size. Understanding this helps write efficient and correct embedded C code.

Practice

(1/5)
1. What does struct packing do in embedded C?
easy
A. Removes extra spaces between fields to save memory
B. Adds extra spaces to align data on memory boundaries
C. Changes the data types of struct members
D. Automatically initializes struct members to zero

Solution

  1. Step 1: Understand struct packing purpose

    Struct packing removes padding bytes between fields to reduce memory usage.
  2. Step 2: Compare with alignment

    Alignment adds padding for faster access, packing removes it to save space.
  3. Final Answer:

    Removes extra spaces between fields to save memory -> Option A
  4. Quick Check:

    Struct packing = removes padding [OK]
Hint: Packing removes spaces, alignment adds spaces [OK]
Common Mistakes:
  • Confusing packing with alignment
  • Thinking packing changes data types
  • Assuming packing initializes values
2. Which of the following is the correct syntax to pack a struct in embedded C using GCC?
easy
A. struct MyStruct { int a; char b; } __packed;
B. struct MyStruct __packed { int a; char b; };
C. struct MyStruct { int a; char b; } __attribute__((aligned));
D. struct __attribute__((packed)) MyStruct { int a; char b; };

Solution

  1. Step 1: Recall GCC packing syntax

    GCC uses __attribute__((packed)) after struct keyword or at end of struct definition.
  2. Step 2: Identify correct placement

    struct __attribute__((packed)) MyStruct { int a; char b; }; places __attribute__((packed)) correctly after struct keyword.
  3. Final Answer:

    struct __attribute__((packed)) MyStruct { int a; char b; }; -> Option D
  4. Quick Check:

    GCC packing syntax = __attribute__((packed)) [OK]
Hint: Use __attribute__((packed)) after struct keyword [OK]
Common Mistakes:
  • Using __packed keyword which is not standard GCC
  • Placing __attribute__((aligned)) instead of packed
  • Putting attributes in wrong position
3. Consider this struct without packing:
struct Example {
  char a;
  int b;
};

sizeof(struct Example);

What is the likely output on a 32-bit system where int is 4 bytes and alignment is on 4-byte boundaries?
medium
A. 5
B. 8
C. 12
D. 16

Solution

  1. Step 1: Analyze struct member sizes and alignment

    char a = 1 byte, int b = 4 bytes aligned on 4-byte boundary.
  2. Step 2: Calculate padding and total size

    After char a, 3 bytes padding added to align int b. Total size = 1 + 3 + 4 = 8 bytes. Struct size must be multiple of largest alignment (4), which 8 satisfies.
  3. Final Answer:

    8 -> Option B
  4. Quick Check:

    Size with padding = 8 bytes [OK]
Hint: Add padding after smaller types to align next member [OK]
Common Mistakes:
  • Ignoring padding bytes
  • Adding padding after last member unnecessarily
  • Assuming size is sum of member sizes only
4. Given this code snippet:
struct Data {
  char c;
  int i;
} __attribute__((packed));

struct Data d;
printf("%zu", sizeof(d));

The output is 5, but the program crashes when accessing d.i. What is the likely cause?
medium
A. Accessing unaligned int causes crash on some systems
B. The struct is not actually packed
C. char c is not initialized
D. printf format specifier is incorrect

Solution

  1. Step 1: Understand packing effect on alignment

    Packing removes padding, so int i may not be aligned on 4-byte boundary.
  2. Step 2: Recognize hardware alignment requirements

    Some systems crash or fault when accessing unaligned int variables.
  3. Final Answer:

    Accessing unaligned int causes crash on some systems -> Option A
  4. Quick Check:

    Unaligned access = crash risk [OK]
Hint: Packed structs can cause unaligned access crashes [OK]
Common Mistakes:
  • Blaming printf format specifier
  • Assuming packing always safe
  • Ignoring hardware alignment rules
5. You have a struct with members:
char a;
short b;
int c;

On a 32-bit system, how can you arrange and pack this struct to minimize memory size without causing unaligned access faults?
hard
A. Order members as char a; int c; short b; and use packing
B. Order members as char a; short b; int c; without packing
C. Order members as int c; short b; char a; and use packing
D. Order members as short b; char a; int c; without packing

Solution

  1. Step 1: Understand alignment requirements

    int requires 4-byte alignment, short 2-byte, char 1-byte.
  2. Step 2: Arrange members largest to smallest

    Ordering int c; short b; char a; places largest first, minimizing padding.
  3. Step 3: Use packing carefully

    Packing removes padding but can cause unaligned access; here, ordering avoids unaligned access.
  4. Final Answer:

    Order members as int c; short b; char a; and use packing -> Option C
  5. Quick Check:

    Largest to smallest + packing = minimal size safe [OK]
Hint: Order largest to smallest type, then pack [OK]
Common Mistakes:
  • Ordering members smallest to largest causing padding
  • Packing without considering alignment faults
  • Ignoring hardware alignment rules
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard