Created
March 19, 2009 00:40
-
-
Save rpj/81510 to your computer and use it in GitHub Desktop.
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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
void* align(void* ptr, int size, int alignment) { | |
printf("pointer is at 0x%x, size is %d, alignment is %d\n", ptr, size, alignment); | |
int mod = ((int)ptr % alignment); | |
void* ret = NULL; | |
if (!mod) { // if the pointer is already aligned as req'd, don't do anything... this makes freeAligned dangerous, though! | |
ret = ptr; | |
} | |
else { | |
void* p = malloc(size + alignment); | |
int align = (alignment - ((int)p % alignment)); | |
printf("mod is %d, align is %d, p is 0x%x\n", mod, align, p); | |
if (align < alignment) { | |
// assign the return pointer to be at a correctly-aligned boundary, and write the byte of accounting | |
*((char*)(ret = ((char*)p) + align) - 1) = align; | |
printf("ret is 0x%x\n", ret); | |
} | |
else { // we got a correctly-aligned pointer from malloc() this time around, yay. also makes freeAligned dangerous. | |
ret = p; | |
} | |
// copy into our new pointer | |
memcpy(ret, ptr, size); | |
free(ptr); | |
} | |
return ret; | |
} | |
void freeAligned(void* ptr) { | |
// peeking back like this is dangerous, because align() doesn't modify already-aligned pointers (though it could and probably should) | |
int backup = (int)*((char*)ptr - 1); | |
printf("freeing aligned: 0x%x - %d -> 0x%x\n", ptr, backup, ((char*)ptr - backup)); | |
free((char*)ptr - backup); | |
} | |
int main() | |
{ | |
void* p1 = malloc(16); | |
void* p2 = malloc(17); | |
void* p3 = malloc(37); | |
void* p4 = malloc(sizeof(int) * 42); | |
void* p5 = malloc(133); | |
void* pa = NULL; | |
bzero(p3, 37); | |
memcpy(p3, "Ryan Joseph", strlen("Ryan Joseph")); | |
printf("as a string: '%s'\n", (char*)p3); | |
printf("aligned: 0x%x\n", (pa = align(p3, 37, 32))); | |
printf("as a string: '%s'\n", (char*)pa); | |
freeAligned(pa); | |
bzero(p5, 133); | |
memcpy(p5, "Foobar", strlen("Foobar")); | |
printf("\nanother:\n"); | |
printf("as a string: '%s'\n", (char*)p5); | |
printf("aligned: 0x%x\n", (pa = align(p5, 133, 64))); | |
printf("as a string: '%s'\n", (char*)pa); | |
printf("one byte before: %d\n", (int)*((char*)pa - 1)); | |
freeAligned(pa); | |
free(p1); | |
free(p2); | |
free(p4); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment