Question
In C, why can the sizeof operator return a value for a struct that is larger than the total of the sizeof values of its individual members?
For example, why might a structure occupy more memory than you would expect by simply adding the sizes of all its fields together?
Short Answer
By the end of this page, you will understand why sizeof(struct) is often larger than the sum of its members in C. You will learn about memory alignment, padding bytes, and how compilers lay out structures in memory for performance and correctness. You will also see examples, common mistakes, and practical ways to inspect and reason about struct size.
Concept
In C, a struct groups multiple values into one type. It may seem natural to assume that the size of a structure should be exactly the sum of the sizes of its members, but that is often not true.
The main reason is alignment.
Different data types usually have preferred memory boundaries where they can be accessed more efficiently. For example:
- a
charoften has alignment 1 - an
intoften has alignment 4 - a
doubleoften has alignment 8
To satisfy these alignment requirements, the compiler may insert padding bytes between members or at the end of the structure.
Why alignment matters
Processors are often faster when data is stored at addresses aligned to the data type's natural boundary. On some systems, misaligned access is slower. On others, it can even cause hardware faults.
So the compiler arranges structure members like this:
- Place each member at an address that satisfies its alignment requirement.
- Insert padding if necessary before the next member.
- Possibly add padding at the end so that arrays of that structure are also properly aligned.
Example idea
Suppose this structure exists on a system where int is 4 bytes and aligned to 4 bytes:
struct Example {
char a;
b;
};
Mental Model
Think of a struct like packing objects into storage boxes on a shelf.
- A small item like a
charis like a coin. - A larger item like an
intis like a book that must sit flat on a shelf section of a certain width.
If you put a coin down first and then want to place a book, you may need to leave some empty space so the book starts in the correct position. That empty space is padding.
At the end of the box, you may also leave some space so that if you line up many identical boxes in a row, each box starts neatly at the right boundary. That is trailing padding.
So sizeof(struct) measures the full box, including the empty spaces needed for neat and efficient placement, not just the items inside it.
Syntax and Examples
In C, you use sizeof to measure the size of a type or object.
sizeof(int)
sizeof(struct MyStruct)
sizeof(variable)
Example 1: Padding between members
#include <stdio.h>
struct Example {
char a;
int b;
};
int main(void) {
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof(int) = %zu\n", sizeof(int));
printf("sizeof(struct Example) = %zu\n", sizeof(struct Example));
return 0;
}
A common result is:
sizeof(char) = 1
sizeof() =
( Example) =
Step by Step Execution
Consider this example:
#include <stdio.h>
struct Sample {
char x;
int y;
};
int main(void) {
struct Sample s;
printf("%zu\n", sizeof(s));
return 0;
}
Let us walk through what often happens on a system where int is 4 bytes and aligned to 4 bytes.
Step 1: Start the struct at offset 0
The structure begins at memory offset 0.
Step 2: Place x
char x;
xneeds 1 byte- it is placed at offset
0
Current used space: 1 byte.
Real World Use Cases
Understanding struct padding matters in many practical situations.
Binary file formats
If you write a struct directly to a file, padding bytes become part of the file layout. This can make the file format compiler-dependent and non-portable.
Network protocols
When sending binary data over a network, relying on raw struct layout is risky. Different systems may use different padding and alignment rules.
Embedded systems
Memory is often limited, so unnecessary padding can matter. Developers may reorder fields to reduce wasted space.
Performance-sensitive code
Alignment can improve CPU performance. Sometimes a slightly larger struct is faster because aligned accesses are more efficient.
Interfacing with hardware or foreign code
When matching a C struct with hardware registers, operating system APIs, or code written in another language, exact layout matters. Developers must understand alignment and packing rules carefully.
Real Codebase Usage
In real projects, developers usually do not just ask "what is the sum of the fields?" They care about layout, portability, and intent.
Common patterns
- Reordering fields to reduce padding
- Using
offsetofto inspect layout when necessary - Avoiding direct serialization of raw structs
- Defining explicit binary formats instead of relying on compiler layout
- Adding static checks in low-level code
Example: reorder to reduce wasted space
struct LessEfficient {
char a;
int b;
char c;
};
struct MoreEfficient {
int b;
char a;
char c;
};
The second version may use less memory on many systems.
Example: validating assumptions
#include <assert.h>
struct Header {
int id;
short type;
short flags;
};
int main(void) {
assert(( Header) == );
;
}
Common Mistakes
Mistake 1: Assuming member sizes always add up exactly
Broken assumption:
struct Data {
char tag;
int value;
};
/* Wrong expectation: sizeof(struct Data) == 5 */
Why it happens:
- ignores alignment and padding
How to avoid it:
- always use
sizeof(struct Data)if you need the real size - do not manually guess struct size
Mistake 2: Using raw structs as portable file or network formats
Broken approach:
fwrite(&data, sizeof data, 1, file);
Why it is risky:
- layout can differ across compilers and platforms
- padding bytes may be included
- endianness may also differ
How to avoid it:
- serialize each field explicitly
- define exact byte-level formats
Mistake 3: Forgetting trailing padding in arrays
struct Item {
int id;
char flag;
};
Comparisons
| Concept | What it means | Includes padding? | Portable across systems? |
|---|---|---|---|
| Sum of member sizes | Add sizeof for each field manually | No | No |
sizeof(struct T) | Actual memory size chosen by compiler | Yes | Depends on platform |
offsetof(struct T, member) | Position of a member inside the struct | Shows layout gaps indirectly | Depends on platform |
| Packed struct | Compiler-specific layout with reduced/removed padding | Often less or none | Less portable |
sizeof(member sum) vs sizeof(struct)
Cheat Sheet
sizeof(struct T)
offsetof(struct T, member)
Key rules
sizeof(struct)may be larger than the sum of member sizes.- The extra space usually comes from padding.
- Padding is added to satisfy alignment requirements.
- Padding can appear:
- between members
- at the end of the struct
- Member order can change the final size.
- Arrays of structs rely on the struct size including any trailing padding.
Example
struct X {
char a;
int b;
};
Common layout:
aat offset 0- padding at offsets 1 to 3
bat offset 4- total size: 8
Tips
- Use
sizeof(struct T)for real size. - Use
offsetofto inspect member positions. - Do not assume raw struct layout is portable.
- Reorder fields if reducing padding matters.
- Be careful with compiler-specific packed structs.
FAQ
Why is sizeof(struct) bigger than the sum of its fields in C?
Because the compiler may add padding bytes to satisfy alignment requirements for faster or valid memory access.
What is padding in a struct?
Padding is unused space inserted by the compiler between members or at the end of a structure.
Why is padding added at the end of a struct?
Trailing padding helps ensure that each element in an array of structs starts at a properly aligned address.
Can I remove struct padding?
Sometimes, with compiler-specific packing features or by reordering members. But removing padding can reduce performance or cause portability problems.
Does every compiler produce the same struct size?
No. Struct layout can vary by compiler, architecture, and ABI.
How can I see where struct members are stored?
Use offsetof() from <stddef.h> to inspect member offsets.
Should I write structs directly to files or sockets?
Usually no, unless you fully control the platform and layout. Explicit serialization is safer and more portable.
Mini Project
Description
Build a small C program that compares the expected sum of structure member sizes with the actual sizeof result. This project helps you see padding and alignment in action and teaches you how member order affects memory usage.
Goal
Create a program that prints member sizes, member offsets, and total struct sizes for two similar structs with different field orders.
Requirements
- Define two structs containing the same members in different orders.
- Print the
sizeofof each member type used. - Print the
offsetofvalue for each member in both structs. - Print the total
sizeofof each struct. - Show which struct is more memory-efficient on your system.
Keep learning
Related questions
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
Definition vs Declaration in C and C++: What’s the Difference?
Learn the difference between declarations and definitions in C and C++ with simple examples, common mistakes, and practical usage.
Difference Between #include <...> and #include "..." in C and C++
Learn the difference between #include with angle brackets and quotes in C and C++, including search paths, examples, and common mistakes.