- C Programming Tutorial
- C - Home
- Basics of C
- C - Overview
- C - Features
- C - History
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Tokens
- C - Keywords
- C - Identifiers
- C - User Input
- C - Basic Syntax
- C - Data Types
- C - Variables
- C - Integer Promotions
- C - Type Conversion
- C - Type Casting
- C - Booleans
- Constants and Literals in C
- C - Constants
- C - Literals
- C - Escape sequences
- C - Format Specifiers
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Unary Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Misc Operators
- Decision Making in C
- C - Decision Making
- C - if statement
- C - if...else statement
- C - nested if statements
- C - switch statement
- C - nested switch statements
- Loops in C
- C - Loops
- C - While loop
- C - For loop
- C - Do...while loop
- C - Nested loop
- C - Infinite loop
- C - Break Statement
- C - Continue Statement
- C - goto Statement
- Functions in C
- C - Functions
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- Pointers in C
- C - Pointers
- C - Pointers and Arrays
- C - Applications of Pointers
- C - Pointer Arithmetics
- C - Array of Pointers
- C - Pointer to Pointer
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Function Pointers
- C - Pointer to an Array
- C - Pointers to Structures
- C - Chain of Pointers
- C - Pointer vs Array
- C - Character Pointers and Functions
- C - NULL Pointer
- C - void Pointer
- C - Dangling Pointers
- C - Dereference Pointer
- C - Near, Far and Huge Pointers
- C - Initialization of Pointer Arrays
- C - Pointers vs. Multi-dimensional Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Special Characters
- C Structures and Unions
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Lookup Tables
- C - Dot (.) Operator
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- File Handling in C
- C - Input & Output
- C - File I/O (File Handling)
- C Preprocessors
- C - Preprocessors
- C - Pragmas
- C - Preprocessor Operators
- C - Macros
- C - Header Files
- Memory Management in C
- C - Memory Management
- C - Memory Address
- C - Storage Classes
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
Structure Padding and Packing in C
What is Structure Padding in C?
Structure padding in C is the process that is handled by the CPU architecture. Structure Padding adds a certain number of empty bytes within a structure so that the data members are naturally aligned in memory. The alignment requirements are determined by the processor architecture rather than the language itself. Naturally, the alignment requirements change as per the data bus size or other architectural considerations of a certain CPU architecture.
Understanding Structure Padding with Examples
Let us define a struct type as follows −
struct struct1 { char x; int y; char z; };
Example 1
Let us check the size in bytes required for a variable of this type −
#include <stdio.h> struct struct1{ char a; char b; int c; }; int main(){ printf("Size: %d", sizeof(struct struct1)); return 0; }
Output
When you run this code, it will produce the following output −
Size: 8
The result is contrary to the expectation.
Considering that a char type needs 1 byte, and an int type needs 4 bytes, one might assume the output should be "1 + 1 + 4 = 6 bytes".
However, the CPU architecture necessitates altering this structure. Considering that we are using a CPU with 32-bit processor, it reads 4 bytes at a time, which means that 1 word is equal to 4 bytes.
In one CPU cycle, it accesses the char "a", then char "b" and the first two bytes of int "c". In the second cycle, the other two bytes are accessed.
Even if we want to read only "c", two CPU cycles are required. For this purpose, the CPU adds two empty bytes before the bytes in which the value of "c" is stored. This mechanism is called as padding.
This now explains the result we obtained above, that of the size of the struct type to be 8 bytes.
Example 2
Let us change the sequence of members in the above struct type, and set the type of "b" and the type of "c".
#include <stdio.h> struct struct1{ char a; int b; char c; }; int main(){ printf("size: %d", sizeof(struct struct1)); return 0; }
Output
Run the code and check its output −
size: 12
Out of the 4 bytes in the first word, the first one is allocated to char "a" followed by three empty bytes.
The next 4 bytes that form the next word are used to store int "b". Subsequently, out of the next group of 4, only one is utilized for "c". However, the struct size is 12.
What is Structure 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. We can use certain pragma directives and attributes to achieve packing.
Understanding Structure Packing with Examples
The padding, forced by the CPU architecture is unavoidable, however there are ways to minimize padding. It can be done with the use of −
- Using #pragma pack(1) directive
- Using packed attribute
Using #pragma pack(1) Directive
The #pragma pack(1) preprocessor directive forces the compiler to disregard the padding, and align the structure members end to end during the memory allocation process.
Example
Let's add this directive at the top of the code used previously, and see the result −
#include <stdio.h> #pragma pack(1) struct struct1{ char a; int b; char c; }; int main(){ printf("size: %d", sizeof(struct struct1)); return 0; }
Output
Run the code and check its output −
size: 6
We can see the structure padding has been avoided and reduced memory wastage.
Using __attribute__((packed))
With GCC, we can use attributes to specify various special properties of structure and union types. The attributes are: aligned, deprecated, packed, transparent_union, unused, and visibility. The syntax of applying these attributes is "__attribute__ ((...))".
Example
Here, we are going to use packed attribute in the definition of our struct type.
#include <stdio.h> struct __attribute__((packed)) struct1{ char a; int b; char c; }; int main(){ printf("size: %d", sizeof(struct struct1)); return 0; }
Output
Run the code and check its output −
size: 6
This method also avoids the effect of padding.