Consider:
struct mystruct_A
{
char a;
int b;
char c;
} x;
struct mystruct_B
{
int b;
char a;
} y;
The sizes of the structures are 12 and 8 respectively.
Are these structures padded or packed?
When does padding or packing take place?
I know this question is old and most answers here explains padding really well, but while trying to understand it myself I figured having a "visual" image of what is happening helped.
The processor reads the memory in "chunks" of a definite size (word). Say the processor word is 8 bytes long. It will look at the memory as a big row of 8 bytes building blocks. Every time it needs to get some information from the memory, it will reach one of those blocks and get it.
As seem in the image above, doesn't matter where a Char (1 byte long) is, since it will be inside one of those blocks, requiring the CPU to process only 1 word.
When we deal with data larger than one byte, like a 4 byte int or a 8 byte double, the way they are aligned in the memory makes a difference on how many words will have to be processed by the CPU. If 4-byte chunks are aligned in a way they always fit the inside of a block (memory address being a multiple of 4) only one word will have to be processed. Otherwise a chunk of 4-bytes could have part of itself on one block and part on another, requiring the processor to process 2 words to read this data.
The same applies to a 8-byte double, except now it must be in a memory address multiple of 8 to guarantee it will always be inside a block.
This considers a 8-byte word processor, but the concept applies to other sizes of words.
The padding works by filling the gaps between those data to make sure they are aligned with those blocks, thus improving the performance while reading the memory.
However, as stated on others answers, sometimes the space matters more then performance itself. Maybe you are processing lots of data on a computer that doesn't have much RAM (swap space could be used but it is MUCH slower). You could arrange the variables in the program until the least padding is done (as it was greatly exemplified in some other answers) but if that's not enough you could explicitly disable padding, which is what packing is.
(The above answers explained the reason quite clear, but seems not totally clear about the size of padding, so, I will add an answer according to what I learn from The Lost Art of C Structure Packing)
Memory align (for struct)
Rules:
e.g on 64 bit system,
int
should start at address divisible by 4, andlong
by 8,short
by 2.char
andchar[]
are special, could be any memory address, so they don't need padding before them.struct
, other than the alignment need for each individual member, the size of whole struct itself will be aligned to a size divisible by size of largest individual member, by padding at end.e.g if struct's largest member is
long
then divisible by 8,int
then by 4,short
then by 2.Order of member:
stu_c
andstu_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)
Rules:
Struct address starts from
(n * 16)
bytes. (You can see in the example below, all printed hex addresses of structs end with0
.)Reason: the possible largest individual struct member is 16 bytes (
long double
).Empty space:
e.g in
test_struct_address()
below, the variablex
resides between adjacent structg
andh
.No matter whether
x
is declared,h
's address won't change,x
just reused the empty space thatg
wasted.Similar case for
y
.Example
(for 64 bit system)
memory_align.c:
Execution result -
test_struct_padding()
:Execution result -
test_struct_address()
:Data structure alignment is the way data is arranged and accessed in computer memory. It consists of two separate but related issues: data alignment and data structure padding. When a modern computer reads from or writes to a memory address, it will do this in word sized chunks (e.g. 4 byte chunks on a 32-bit system) or larger. Data alignment means putting the data at a memory address equal to some multiple of the word size, which increases the system’s performance due to the way the CPU handles memory. To align the data, it may be necessary to insert some meaningless bytes between the end of the last data structure and the start of the next, which is data structure padding.
Structure packing suppresses structure padding, padding used when alignment matters most, packing used when space matters most.
Some compilers provide
#pragma
to suppress padding or to make it packed to n number of bytes. Some provide keywords to do this. Generally pragma which is used for modifying structure padding will be in the below format (depends on compiler):For example ARM provides the
__packed
keyword to suppress structure padding. Go through your compiler manual to learn more about this.So a packed structure is a structure without padding.
Generally packed structures will be used
to save space
to format a data structure to transmit over network using some protocol (this is not a good practice of course because you need to
deal with endianness)
Padding and packing are just two aspects of the same thing:
In
mystruct_A
, assuming a default alignment of 4, each member is aligned on a multiple of 4 bytes. Since the size ofchar
is 1, the padding fora
andc
is 4 - 1 = 3 bytes while no padding is required forint b
which is already 4 bytes. It works the same way formystruct_B
.Padding aligns structure members to "natural" address boundaries - say,
int
members would have offsets, which aremod(4) == 0
on 32-bit platform. Padding is on by default. It inserts the following "gaps" into your first structure: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: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.