sizeof(x)
returns 2 for the structure below
struct s {
short c;
} x;
but for the structure
struct s {
short c;
char a;
} x;
sizeof(x)
returns 4
, Why?
The second one gets one padding byte (assuming short is 2 bytes long and char 1 byte long). Shouldn't the first structure have 2 padding bytes then (and thus be 4 bytes long)?
In Structure, sometimes the size of the structure is more than the size of all structures members because of structure padding. Note: But what actual size of all structure member is 13 Bytes. So here total 3 bytes are wasted. So, to avoid structure padding we can use pragma pack as well as an attribute.
The answer to that lies in how a CPU accesses memory. Typically a CPU has alignment constraints, e.g. a CPU will access one word at a time, or a CPU will require data to be 16byte aligned, etc. So to make sure that data is aligned according to the constraints of the CPU, padding is required.
The structural padding is an in-built process that is automatically done by the compiler. Sometimes it required to avoid the structure padding in C as it makes the size of the structure greater than the size of the structure members. We can avoid the structure padding in C in two ways: Using #pragma pack(1) directive.
The compiler will insert a padding byte after the char to ensure short int will have an address multiple of 2 (i.e. 2 byte aligned).
The predominant use of padding is to align structure members as required by the hardware (or other aspects of the C implementation). An algorithm for laying out data in a struct is in this answer.
To answer the question in your title, when do structures not have padding: A structure does not require padding for alignment if each member’s alignment requirement is a divisor of the total size of all preceding members and of the total size of all members. (A C implementation may still add padding for reasons other than alignment, but that is a bit unusual.)
For your examples, let’s suppose, in a C implementation, short
is two bytes in size and requires two-byte alignment. By definition, char
is one byte and requires one-byte alignment.
Then, in struct s {short c;}
:
c
is put at the beginning of the struct
. There is never any padding at the beginning.struct
, the next struct s
will begin two bytes beyond the first, and its member c
will still be at a multiple of two bytes, so it is aligned correctly.In contrast, in struct s {short c; char a;}
:
c
is put at the beginning.a
is put two bytes after c
. This is fine, since a
only requires one-byte alignment.struct
is three bytes. Then, if we make an array of these struct
, the next struct s
will begin three bytes from the start.struct s
, the c
member will be at an offset of three bytes. That violates the alignment requirement for short
.struct
work, we must add one byte of padding. This makes the total size four bytes. Then, in an array of these struct
, all the members will be at boundaries required by their alignment.Even if you declare just a single object of a structure, as in struct s {short c; char a;} x;
, a structure is always laid out so it can be used in an array.
The first structure has one element of size 2 (assuming short
has size 2 on your system). It is as good as directly having an array of short directly.
The second structure is a special thing: access to short
variables is best done on even addresses. If we hadn't padding, we had the following:
struct s arr[5]; // an array
void * a = arr; // needed to reference it
Then,
arr[0].c
is at a
.arr[0].a
is at a
+ 2 bytes.arr[1].c
is at a
+ 3 bytes (!).arr[1].a
is at a
+ 5 bytes (!).As it is preferrable to have arr[1].c
at an even address, we add padding. Then,
arr[1].c
is at a
+ 4 bytes.arr[1].a
is at a
+ 6 bytes.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With