Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check alignment of returned data in the malloc() implementation?

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

?

like image 475
Anatoly Avatar asked Nov 01 '22 05:11

Anatoly


1 Answers

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).

like image 90
yachoor Avatar answered Nov 15 '22 05:11

yachoor