Created
August 30, 2017 22:11
-
-
Save dblalock/255e76195676daa5cbc57b9b36d1c99a to your computer and use it in GitHub Desktop.
C / C++ portable aligned memory allocation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Not really sure who still uses non-power of two aligned memory and why alignment is part of the memory (counter to what alignment typically is in C and C++).
With for example 16-byte alignment this simplifies to
void * ptr = (void *)(((uintptr_t)mem+15) & ~ (uintptr_t)0x0F);
and generally one can do bit shifts instead of more expensive modulo.However, this one is much simpler. Feel free to reuse/adjust for storing the alignment: