Reputation:
I´m working on a memory manager using help of the book Game Engine Architecture.
At the moment I´m reading about memory alignment (in the book and web) and I´m not sure how the alignment is used correctly for classes. I understand the concept of memory alignment (e.g. a 4 byte data chunk should be located at an address ending with 0x0, 0x4, 0x8 or 0xC) but at the allocateAligned()
-function in the book is a comment that says that the alignment has to be power of two. If i have a class that has two int
´s and one char
, sizeof(classs)
tells me, that the class is 12 bytes big. So, would you pass 32 as alignment? Would it not be a waste of memory and maybe lead to fragmentation?
My question is, how do classes have to be aligned correctly, could you explain me it more detailed (what happens if you want to align bigger data chunks, like 121 bytes) and does it make sense for the bigger chunks to be aligned (because the processor fetches only 8 bytes in one call, if I´m informed right)?
Upvotes: 7
Views: 6026
Reputation: 354999
The alignment of a type can never be greater than the size of a type. This is because in an array, there can be no padding between elements.
Just as importantly, though, the alignment of a type may be smaller than the size of the type.
Let's consider your class type: it has three members, two 4-byte integers and one 2-byte integer. Let's assume that the alignment of a 4-byte integer is 4 bytes and the alignment of a 2-byte integer is 2 bytes (this is common). In this case, the alignment of your class type is only 4 bytes. It can be located on any 4-byte boundary and each of its members will be correctly aligned.
This is why your class type has two bytes of padding: 12 is evenly divisible by four, but 10 is not. If your class had no padding, its size would only be 10 bytes, and in an array of elements half of the objects would be misaligned.
Upvotes: 7
Reputation: 72271
A type's alignment can be smaller than, but not bigger than, its size. On a typical 32-bit implementation, your
struct X {
int a;
int b;
char c;
};
would likely have sizeof(X) == 12
and alignof(X) == 4
. Obviously you can't have an X
every four bytes because they would then overlap, but the alignment means that 0x1000
, 0x1004
, 0x1008
, and 0x100c
are all potential places you might begin an X
.
Note that the type size as returned by sizeof
is always a multiple of the alignment, since sizeof
specifies the number of bytes between array elements, and you wouldn't want the first entry in an array to be aligned but not the second.
Upvotes: 2