Skip to content

Instantly share code, notes, and snippets.

@mastbaum
Created June 21, 2011 16:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mastbaum/1038287 to your computer and use it in GitHub Desktop.
Save mastbaum/1038287 to your computer and use it in GitHub Desktop.
dynamically casting based on a header in a struct
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
#include<string.h>
#include<jemalloc/jemalloc.h>
typedef struct
{
uint32_t type;
} Header;
typedef struct
{
Header header;
uint32_t data;
} Foo;
typedef struct
{
Header header;
char data[15];
} Bar;
int main(int argc, char* argv[])
{
// for structs that start with a header
Foo* foo = malloc(sizeof(Foo));
foo->data = 12345;
foo->header.type = 42;
Bar* bar = malloc(sizeof(Bar));
strncpy(bar->data, "hello!", 7);
bar->header.type = 1;
// we can reinterpret them as just the header (though allocating space for the biggest possible thing)
Header* h = malloc(sizeof(Bar));
h = (Header*) foo; // reinterpret
printf("h (%p): type = %i (%lu bytes, %lu usable)\n", h, h->type, sizeof(h), malloc_usable_size(h)); // it works!
// then cast back based on type
if(h->type == 42) {
Foo* newfoo = realloc(h, sizeof(Foo));
printf("newfoo (%p): %lu bytes, %lu usable\n", newfoo, sizeof(newfoo), malloc_usable_size(newfoo));
printf("newfoo (%p): header.type = %i\n", newfoo, newfoo->header.type);
printf("newfoo (%p): data = %i\n", newfoo, newfoo->data);
}
if(h->type == 1) {
Bar* newbar = realloc(h, sizeof(Bar));
printf("newbar (%p): %lu bytes, %lu usable\n", newbar, sizeof(newbar), malloc_usable_size(newbar));
printf("newbar (%p): header.type = %i\n", newbar, newbar->header.type);
printf("newbar (%p): data = %s\n", newbar, newbar->data);
}
return 0;
}
/**************************************
OUTPUT:
CASE 1: foo (l. 37: h = (Header*) foo;)
h (0x7f60bd406058): type = 42 (8 bytes, 8 usable)
newfoo (0x7f60bd406058): 8 bytes, 8 usable
newfoo (0x7f60bd406058): header.type = 42
newfoo (0x7f60bd406058): data = 12345
CASE 2: bar (l. 37: h = (Header*) bar;)
h (0x7fa615407040): type = 1 (8 bytes, 32 usable)
newbar (0x7fa615407040): 8 bytes, 32 usable
newbar (0x7fa615407040): header.type = 1
newbar (0x7fa615407040): data = hello!
****************************************/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment