Skip to content

Instantly share code, notes, and snippets.

@rpj
Created March 19, 2009 00:40
Show Gist options
  • Save rpj/81510 to your computer and use it in GitHub Desktop.
Save rpj/81510 to your computer and use it in GitHub Desktop.
#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