Dynamic_Alloc

Run Settings
LanguageC
Language Version
Run Command
#include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <assert.h> #define DYNAMIC_ALLOC_SIGNATURE_USED ((size_t)0xA888A8A8A8A8A0A8) #define DYNAMIC_ALLOC_SIGNATURE_FREE ((size_t)0x8880A0A8A0A0A088) #define DYNAMIC_ALLOC_SIGNATURE_BITS ((size_t)0x2008080008080020) typedef struct Dynamic_Alloc_Preamble Dynamic_Alloc_Preamble; struct Dynamic_Alloc_Preamble { Dynamic_Alloc_Preamble *next; size_t is_allocated; }; size_t mem_pool_raw[4096 * 4 / sizeof(size_t)]; char *mem_pool = (char *)mem_pool_raw; Dynamic_Alloc_Preamble *mem_next = (Dynamic_Alloc_Preamble *)mem_pool_raw; void dynamic_print() { Dynamic_Alloc_Preamble *preamble = (Dynamic_Alloc_Preamble *)mem_pool; size_t used_mem = 0; size_t free_mem = 0; size_t used_blocks = 0; size_t free_blocks = 0; while(true) { if(preamble->is_allocated == 0) { break; } else if(preamble->is_allocated == DYNAMIC_ALLOC_SIGNATURE_USED) { used_mem += (char *)preamble->next - (char *)preamble; used_blocks += 1; } else if(preamble->is_allocated == DYNAMIC_ALLOC_SIGNATURE_FREE) { free_mem += (char *)preamble->next - (char *)preamble; free_blocks += 1; } preamble = preamble->next; } printf("Total Mem: %zu, Blocks: %zu\n", used_mem + free_mem, used_blocks + free_blocks); printf("Used Mem: %zu, Blocks: %zu\n", used_mem, used_blocks); printf("Free Mem: %zu, Blocks: %zu\n", free_mem, free_blocks); } void dynamic_defrag() { mem_next = (Dynamic_Alloc_Preamble *)mem_pool_raw; } void dynamic_atomic_store(size_t *t, size_t v) { *t = v; } void *dynamic_alloc(size_t size) { size_t mask_size = sizeof(size_t) * 2 - 1; size_t allocation_size = (size + sizeof(Dynamic_Alloc_Preamble) + mask_size) & ~mask_size; Dynamic_Alloc_Preamble *preamble = mem_next; while(true) { if(preamble->is_allocated == 0) { break; } else if(preamble->is_allocated == DYNAMIC_ALLOC_SIGNATURE_USED) { preamble = preamble->next; continue; } else if(preamble->is_allocated == DYNAMIC_ALLOC_SIGNATURE_FREE) { Dynamic_Alloc_Preamble *next_used_preamble = preamble->next; while(true) { if(next_used_preamble->is_allocated == 0) { preamble->next = 0; preamble->is_allocated = 0; goto continue_outer; } else if(next_used_preamble->is_allocated == DYNAMIC_ALLOC_SIGNATURE_USED) { preamble->next = next_used_preamble; break; } else if(next_used_preamble->is_allocated == DYNAMIC_ALLOC_SIGNATURE_FREE) { next_used_preamble = next_used_preamble->next; continue; } assert(0 && "heap corruption"); return 0; } if(allocation_size <= (size_t)next_used_preamble - (size_t)preamble) break; preamble = preamble->next; continue_outer: continue; } assert(0 && "heap corruption"); return 0; } preamble->next = (Dynamic_Alloc_Preamble *)((char *)preamble + allocation_size); mem_next = preamble->next; dynamic_atomic_store(&preamble->is_allocated, DYNAMIC_ALLOC_SIGNATURE_USED); return (void *)(preamble + 1); } void dynamic_dealloc(void *ptr) { Dynamic_Alloc_Preamble *preamble = (Dynamic_Alloc_Preamble *)ptr - 1; size_t signature = preamble->is_allocated; if((signature & ~DYNAMIC_ALLOC_SIGNATURE_BITS) == DYNAMIC_ALLOC_SIGNATURE_FREE) { if((signature & DYNAMIC_ALLOC_SIGNATURE_BITS) == DYNAMIC_ALLOC_SIGNATURE_BITS) { preamble->is_allocated = DYNAMIC_ALLOC_SIGNATURE_FREE; return; } else { // Double free assert(0 && "double dealloction\n"); return; } } assert(0 && "heap corruption"); } int main(int argc, char **argv) { int *a1 = dynamic_alloc(4); int *b1 = dynamic_alloc(4); int64_t *c1 = dynamic_alloc(8); void *d1 = dynamic_alloc(0); dynamic_dealloc(a1); dynamic_dealloc(b1); dynamic_dealloc(c1); //dynamic_dealloc(d1); dynamic_defrag(); int *a2 = dynamic_alloc(4); int64_t *c2 = dynamic_alloc(256); dynamic_defrag(); int64_t *e1 = dynamic_alloc(8); dynamic_dealloc(e1); dynamic_print(); return 0; }
Editor Settings
Theme
Key bindings
Full width
Lines