├── README.md ├── mal.c └── memalloc.so /README.md: -------------------------------------------------------------------------------- 1 | ## a simple memory allocator 2 | 3 | It is a simple memory allocator which I write to learn c. Tutorial followed: https://arjunsreedharan.org/post/148675821737/memory-allocators-101-write-a-simple-memory 4 | 5 | I learn more c than any tutorial. 6 | -------------------------------------------------------------------------------- /mal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | typedef char ALIGN[16]; 7 | 8 | // union size is larger than its member so it make sure that end of the header is memory aligned 9 | union header{ 10 | struct { 11 | // storing the size of block and if it is free or not in block 12 | size_t size; 13 | unsigned is_free; 14 | // using linked list to keep track of the memory allocated by our malloc 15 | union header *next; 16 | } s; 17 | 18 | // allocator will be aligned to 16 bytes i.e force the header to be aligned to 16 bytes 19 | ALIGN stub; 20 | }; 21 | typedef union header header_t; 22 | 23 | // to keep track of list 24 | header_t *head= NULL, *tail=NULL; 25 | 26 | // to prevent two or more threads from concurrently accessing memory, we put a basic locking mechanism 27 | pthread_mutex_t global_malloc_lock; 28 | 29 | header_t *get_free_block(size_t size){ 30 | header_t *curr = head; 31 | while(curr){ 32 | if (curr -> s.is_free && curr -> s.size >= size){ 33 | return curr; 34 | } 35 | curr = curr -> s.next; 36 | } 37 | return NULL; 38 | } 39 | 40 | // determine if the block is free or not and if yes, then we can realse it to the OS 41 | void free(void *block){ 42 | header_t *header, *tmp; 43 | void *programbreak; 44 | 45 | if(!block){return;} 46 | 47 | pthread_mutex_lock(&global_malloc_lock); 48 | // We cast block to a header pointer type and move it behind by 1 unit 49 | header = (header_t*)block - 1; 50 | 51 | // gives the current value of program break 52 | programbreak = sbrk(0); 53 | /* check if the block to be freed at the end of the head or not. 54 | if it is, then we can shrink heap size and realase the memory to OS */ 55 | if((char*)block + header->s.size == programbreak){ 56 | if(head == tail){head = tail = NULL;} 57 | else{ 58 | tmp = head; 59 | while(tmp){ 60 | if(tmp -> s.next == tail){ 61 | tmp -> s.next = NULL; 62 | tail = tmp; 63 | } 64 | tmp = tmp->s.next; 65 | } 66 | } 67 | /*sbrk with negative argument decrements the program break 68 | So memory is released by the program to OS*/ 69 | sbrk(0 - header->s.size - sizeof(header_t)); 70 | pthread_mutex_unlock(&global_malloc_lock); 71 | return; 72 | } 73 | header -> s.is_free = 1; 74 | pthread_mutex_unlock(&global_malloc_lock); 75 | } 76 | 77 | void *malloc(size_t size){ 78 | size_t total_size; 79 | void *block; 80 | header_t *header; 81 | if(!size){return NULL;} 82 | pthread_mutex_lock(&global_malloc_lock); 83 | 84 | header = get_free_block(size); 85 | if(header){ 86 | /*found a free block to accomodate requested memory.*/ 87 | header -> s.is_free=0; 88 | pthread_mutex_unlock(&global_malloc_lock); 89 | return NULL; 90 | } 91 | 92 | total_size = sizeof(header_t) + size; 93 | block = sbrk(total_size); 94 | if (block == (void*)-1){ 95 | pthread_mutex_unlock(&global_malloc_lock); 96 | return NULL; 97 | } 98 | 99 | header = block; 100 | header -> s.size = size; 101 | header -> s.is_free = 0; 102 | header -> s.next = NULL; 103 | 104 | if(!head){head = header;} 105 | if(tail){tail -> s.next = header;} 106 | tail = header; 107 | pthread_mutex_unlock(&global_malloc_lock); 108 | return (void*)(header + 1); 109 | } 110 | 111 | // allocates memory for an array of num elements of nsize bytes each and returns a points to the allocated memory 112 | void *calloc(size_t num, size_t nsize){ 113 | size_t size; 114 | void *block; 115 | if(!num || !nsize){return NULL;} 116 | size = num * nsize; 117 | // check mul overflow 118 | if(nsize != size/num){return NULL;} 119 | block = malloc(size); 120 | if(!block){return NULL;} 121 | // memset: fill memory with a constant byte 122 | memset(block, 0, size); 123 | return block; 124 | } 125 | 126 | // change size of the given memory block 127 | void *realloc(void *block, size_t size){ 128 | // if block has the requested size, then do nothing 129 | header_t *header; 130 | void *ret; 131 | 132 | // if it don't have the requested size, call malloc() to get a block of the request size 133 | if(!block || !size){return malloc(size);} 134 | 135 | header = (header_t*)block - 1; 136 | 137 | if (header -> s.size >= size){return block;} 138 | 139 | // memcpy: copy memory area 140 | ret = malloc(size); 141 | if (ret){ 142 | memcpy(ret, block, header -> s.size); 143 | free(block); 144 | } 145 | return ret; 146 | } 147 | 148 | /* A debug function to print the entire link list */ 149 | void print_mem_list() 150 | { 151 | header_t *curr = head; 152 | printf("head = %p, tail = %p \n", (void*)head, (void*)tail); 153 | while(curr) { 154 | printf("addr = %p, size = %zu, is_free=%u, next=%p\n", 155 | (void*)curr, curr->s.size, curr->s.is_free, (void*)curr->s.next); 156 | curr = curr->s.next; 157 | } 158 | } 159 | 160 | int main(){ 161 | // Initialize the mutex 162 | pthread_mutex_init(&global_malloc_lock, NULL); 163 | 164 | printf("Testing custom memory allocator\n\n"); 165 | 166 | // Allocate some memory 167 | int *arr1 = (int*)malloc(5 * sizeof(int)); 168 | int *arr2 = (int*)calloc(3, sizeof(int)); 169 | 170 | // Print the memory list 171 | printf("After allocations:\n"); 172 | print_mem_list(); 173 | 174 | // Free some memory 175 | free(arr1); 176 | 177 | // Print the memory list again 178 | printf("\nAfter freeing arr1:\n"); 179 | print_mem_list(); 180 | 181 | // Reallocate some memory 182 | arr2 = (int*)realloc(arr2, 5 * sizeof(int)); 183 | 184 | // Print the memory list one more time 185 | printf("\nAfter reallocation:\n"); 186 | print_mem_list(); 187 | 188 | // Clean up 189 | free(arr2); 190 | 191 | } 192 | -------------------------------------------------------------------------------- /memalloc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/angkul07/memory_allocator/3cf7b88ab07a47abe52117920568a614ae7b1f83/memalloc.so --------------------------------------------------------------------------------