Skip to content

Instantly share code, notes, and snippets.

@dblalock
Created August 30, 2017 22:11
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dblalock/255e76195676daa5cbc57b9b36d1c99a to your computer and use it in GitHub Desktop.
Save dblalock/255e76195676daa5cbc57b9b36d1c99a to your computer and use it in GitHub Desktop.
C / C++ portable aligned memory allocation
/* Allocate aligned memory in a portable way.
*
* Memory allocated with aligned alloc *MUST* be freed using aligned_free.
*
* @param alignment The number of bytes to which memory must be aligned. This
* value *must* be <= 255.
* @param bytes The number of bytes to allocate.
* @param zero If true, the returned memory will be zeroed. If false, the
* contents of the returned memory are undefined.
* @returns A pointer to `size` bytes of memory, aligned to an `alignment`-byte
* boundary.
*/
void *aligned_alloc(size_t alignment, size_t size, bool zero) {
size_t request_size = size + alignment;
char* buf = (char*)(zero ? calloc(1, request_size) : malloc(request_size));
size_t remainder = ((size_t)buf) % alignment;
size_t offset = alignment - remainder;
char* ret = buf + (unsigned char)offset;
// store how many extra bytes we allocated in the byte just before the
// pointer we return
*(unsigned char*)(ret - 1) = offset;
return (void*)ret;
}
/* Free memory allocated with aligned_alloc */
void aligned_free(void* aligned_ptr) {
int offset = *(((char*)aligned_ptr) - 1);
free(((char*)aligned_ptr) - offset);
}
@karanbale
Copy link

I think in that case, we need to add a check that sets offset to length of alignment and that should fix it.

@dblalock
Copy link
Author

In the case that remainder == 0, we get offset = alignment, not offset = 0. So it doesn't end up out of bounds.

@kaan2463
Copy link

kaan2463 commented Mar 7, 2024

Thank you for this implementation.
But in C++ I stored offset at the end of the array.
I modified the code like char* buf = new char[alignment + type_size * size + sizeof(size_t)]; and the offset stored by *((size_t*)((char*)buf+ type_size * size)) = (size_t)alignment - remainder;.
And to free the pointer:

size_t size = mSize;
size_t type_size = sizeof(double);
size_t offset = *((size_t*)((char*)data+ type_size * size));
delete[]((char*)mImagData - offset);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment