malloc(sz) returns memory whose alignment works for any object.
On x86 32-bit machines, this means that the address value returned by malloc() should be evenly divisible by 4. But in practice, 32-bit malloc implementations return 8-byte aligned memory, which means that the returned addresses are always uniformly divisible by 8. You must do this too. (On x86-64 / IA-64 machines, the maximum data alignment is 8, but the malloc implementation returns 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 allocates more space than requested by the user. The first part of this space is used to store distribution metadata, including allocated size.
sizeof(metadata) % 8 == 0
But my bunch
static char heap[Heap_Capacity];
starting from a value that is not divisible by 8
metadata* block = (metadata*)heap; (uintptr_t)block % 8 != 0
My tests fail, what can I do in this situation? How to make sure an array starts with an address that
metadata* block = (metadata*)heap; (uintptr_t)block % 8 == 0
?
source share