Reputation: 40593
Let's say that I define the following structure:
struct MyData {
int a;
char b;
int c;
byte d;
byte e;
}
I vaguely remember reading that the size of that structure not only depends on the data type but also memory alignment. On a 32bits CPU, the MyData structure would be 4 bytes + 1 byte + 4 bytes + 1 byte + 1 byte = 11 bytes. Here's my question, is memory alignement increases the size of the structure: 4 bytes + 1 byte (+3 bytes padding) + 4 bytes + 1 byte (+3 bytes padding) + 1 byte (+3 bytes padding) = 20 bytes.
Is this wrong? Am I missing something? Is this something language specific? Can I pack the structure? If so, what would be the advantages and disadvantages?
Thanks!
Upvotes: 0
Views: 2092
Reputation: 70949
You are not wrong in stating that memory alignment can increase the size of the structure; however, any guesses as to how the memory will be aligned are not valid for all platforms. This is strictly platform specific.
Basically, most platforms tend to align on ${WORDSIZE}, or if the data type is smaller than ${WORDSIZE}, then it aligns on the next available fraction of ${WORDSIZE}
For example, if you have a 32 bit word, and you are storing 16 bit shorts, they might align on bits zero and sixteen within a word. But that's not a guarantee, as it is truly platform specific.
To tweak your structs for smaller waste due to padding, order the elements by data type, with the larger data types first. This tends to allow multiple bytes to be packed into the same word (if possible) and the larger than word items will nicely terminate on word boundaries as they tend to be clean multiples of a word (quadword, doubleword, ...)
Upvotes: 2
Reputation: 11896
Yes, compilers will naturally align types on boundaries that match their size. You can force structure packing using compiler pragmas such as
#pragma pack(1)
You can also avoid some padding by reordering your declarations to put your ints at the beginning and single bytes after that.
You can easily test this by printing sizeof(struct MyData)
Upvotes: 0
Reputation: 183978
The compiler can pad the structure as it sees fit. Typically, the two last byte
s would not be separated by padding, so the size would become 4 (int) + 1 (char) + 3 (padding) + 4 (int) + 1 (byte) + 1 (byte) + 2 (padding) = 16
.
Many compilers allow packing the struct per a pragma. The advantage of that is less memory usage, the disadvantage slower reads for the non-aligned int
members.
Upvotes: 2
Reputation: 145899
There is unspecified padding between and after struct members. There is no padding before the first struct member, that is:
struct MyData bla;
int val = (char *) &bla == (char *) &bla.a; // val is 1
A pointer to the structure (suitably converted) points to the first structure member.
The size of the structure object takes into account the padding and is equal to the sum of the size of the members + the sum of the size of the unspecified paddings.
Upvotes: 1