Reputation: 69934
I am writing a custom arena allocator, which allocates blocks of varying sizes from a large buffer. However, I want to ensure that the addresses returned by it are always appropriately aligned, similarly to how malloc
always returns suitably-aligned pointers.
#define ALIGN 16
char buffer[2048];
char *next = buffer;
// Allocates a block of memory, ensuring that "next"
// is always a multiple of ALIGN.
void *alloc(size_t nbytes)
{
void *ret = next;
next += (nbytes + ALIGN - 1) & ~(ALIGN - 1);
return ret;
}
int main()
{
void *p1 = alloc(1);
void *p2 = alloc(5);
void *p3 = alloc(17);
// ...
}
Is there a way to find out what is the appropriate memory alignment that I should use for the platform my code is being compiled for? Or should I just set ALIGN to a large enough constant, as I do in the code example?
Upvotes: 2
Views: 457
Reputation: 140950
Is there a way to find out what is the appropriate memory alignment that I should use
If it's going to be simple obstack
implementation, you could pass the type alignment requirements to your alloc
function, thus possibly reducing memory usage.
#include <stdalign.h> // from C11
void *super_alloc(size_t alignment, size_t size, size_t count);
int *five_ints = super_alloc(alingof(int), sizeof(int), 5);
#define SUPER_ALLOC(type, count) \
((TYPE*)super_alloc(alignof(TYPE), sizeof(TYPE), (count)))
double *seven_doubles = SUPER_ALLOC(double, 7);
Before C11 you may write compiler specific code along #define alignof(type) compiler_specific_code_here(type)
. There are aligned_alloc
and posix_memalign
.
for the platform my code is being compiled for?
When you know the platform, then you know it. Research the documentation of that specific platform you are compiling for and find out it's maximum required alignment for any types.
In C11 there is max_align_t
that you could use and it should be set by your compiler:
static const size_t ALIGN = alignof(max_align_t);
You could potentially take all types and write a big MAX(alignof(int), alignof(long int), alignof(double), alignof(long double)
function-switch with all the types.
Or should I just set ALIGN to a large enough constant, as I do in the code example?
That said, 16
is going to be most probably definitely enough for 99,9% platforms out there, but feel like a waste on platforms with smaller alignment requirements.
Upvotes: 3