malloc(sz)
returns memory whose alignment works for any object.
On 32-bit x86 machines, this means that the address value returned by malloc()
must be evenly divisible by 4. But in practice, 32-bit malloc implementations return 8-byte aligned memory, meaning that returned addresses are always evenly divisible by 8. You should do this too. (On x86-64/IA-64 machines, the maximum data alignment is 8, but malloc implementations return 16-byte aligned memory.)
I have a test for this situation
// Check alignment of returned data.
int main()
{
double* ptr = (double*) malloc(sizeof(double));
assert((uintptr_t) ptr % __alignof__(double) == 0);
assert((uintptr_t) ptr % __alignof__(unsigned long long) == 0);
char* ptr2 = (char*) malloc(1);
assert((uintptr_t) ptr2 % __alignof__(double) == 0);
assert((uintptr_t) ptr2 % __alignof__(unsigned long long) == 0);
}
My malloc code allocate more space than the user requested. The first part of that space is used to store metadata about the allocation, including the allocated size.
sizeof(metadata) % 8 == 0
But my heap
static char heap[Heap_Capacity];
starting with value that not divided by 8
metadata* block = (metadata*)heap;
(uintptr_t)block % 8 != 0
My tests fails, what can I do in this situation? How to be sure that the array begins with address that
metadata* block = (metadata*)heap;
(uintptr_t)block % 8 == 0
?
You could use a union to force correct alignment (see Union element alignment) or calculate starting index for allocation that is correctly aligned (which could reduce your heap capacity by up to 7 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