In C++, the order of members inside a struct can change its total size because the compiler adds padding bytes for alignment.
Example:
#include <iostream>
using namespace std;
struct A {
char c; // 1 byte
int i; // 4 bytes
double d; // 8 bytes
};
struct B {
double d; // 8 bytes
int i; // 4 bytes
char c; // 1 byte
};
int main() {
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
}
Typical result on a 64-bit system:
sizeof(A) = 16
sizeof(B) = 16
Now a clearer example:
struct C {
char c1; // 1 byte
double d; // 8 bytes
char c2; // 1 byte
};
struct D {
double d; // 8 bytes
char c1; // 1 byte
char c2; // 1 byte
};
Typical sizes:
sizeof(C) = 24
sizeof(D) = 16
Why?
For C:
char c1 -> 1 byte
padding -> 7 bytes, so double starts at 8-byte boundary
double d -> 8 bytes
char c2 -> 1 byte
tail padding -> 7 bytes, so total size is multiple of 8
Total = 24 bytes
For D:
double d -> 8 bytes
char c1 -> 1 byte
char c2 -> 1 byte
tail padding -> 6 bytes
Total = 16 bytes
So this:
struct C {
char c1;
double d;
char c2;
};
is larger than this:
struct D {
double d;
char c1;
char c2;
};
because D groups larger aligned members first and smaller members after.
A common rule is:
Order struct members from largest alignment requirement to smallest.
For example:
struct Better {
double d;
int i;
short s;
char c;
};
Instead of:
struct Worse {
char c;
double d;
short s;
int i;
};
This reduces padding and can save memory, especially when you create many objects in an array.
what is padding
Padding is extra unused memory that the compiler inserts inside or at the end of a struct so that each member is placed at a memory address suitable for its alignment.
For example:
struct Example {
char c; // 1 byte
int i; // 4 bytes
};
You might expect:
1 + 4 = 5 bytes
But usually:
sizeof(Example) == 8
because the compiler adds 3 padding bytes after char c so that int i starts at an address divisible by 4.
Memory layout:
byte: 0 1 2 3 4 5 6 7
c padding int i
Why padding is needed:
int usually wants 4-byte alignment
double usually wants 8-byte alignment
So the compiler arranges memory like this:
struct A {
char c; // 1 byte
// 7 bytes padding
double d; // 8 bytes
};
Typical size:
sizeof(A) = 16
Without padding, double d could start at an unaligned address, which may be slower or even invalid on some CPU architectures.
There is also tail padding at the end:
struct B {
int i; // 4 bytes
char c; // 1 byte
};
Expected size:
4 + 1 = 5 bytes
Typical actual size:
sizeof(B) = 8
The compiler adds 3 bytes at the end so that arrays work correctly:
B arr[2];
Each B object must start at the correct alignment boundary.
So in simple words:
Padding is empty space added by the compiler to keep data members properly aligned in memory.