How allocate memory which is page size aligned?

c, linux, memory, memory-management

Solution

There are functions for this that you're supposed to use.

If you can't, for whatever reason, then the way this is generally done is by adding the block size to the allocation size, then using integer-math trickery to round the pointer.

Something like this:

/* Note that alignment must be a power of two. */
void * allocate_aligned(size_t size, size_t alignment)
{
  const size_t mask = alignment - 1;
  const uintptr_t mem = (uintptr_t) malloc(size + alignment);
  return (void *) ((mem + mask) & ~mask);
}

This has not been very deeply tested but you get the idea.

Note that it becomes impossible to figure out the proper pointer to `free()` the memory later. To fix that, we would have to add some additional machinery:

typedef struct {
  void *aligned;
} AlignedMemory;

AlignedMemory * allocate_aligned2(size_t size, size_t alignment)
{
  const size_t mask = alignment - 1;
  AlignedMemory *am = malloc(sizeof *am + size + alignment);
  am->aligned = (void *) ((((uintptr_t) (am + 1)) + mask) & ~mask);
  return am;
}

This wraps the pointer trickery a bit, and gives you a pointer you can `free()`, but you need to dereference into the `aligned` pointer to get the properly aligned pointer.

Problem

I need to allocate memory which should be page size aligned. I need to pass this memory to an `ASM` code which calculates xor of all data blocks. I need to do this with `malloc()`.

Original source