void *check_add_elem_and_sbrk(void *ptr_to_ret, size_t size) { if (add_elem_in_list(g_str->nb_of_elems) == -1) return (NULL); if ((ptr_to_ret = my_sbrk(size)) == (void*)-1) return (NULL); return (ptr_to_ret); }
/*~~~~~~~~~~~~~HELPER FUNCTIONS~~~~~~~~~~~~~*/ static void setupHeap() { freelist[7] = my_sbrk(SBRK_SIZE); // if there is no space on the heap if ((int)freelist[7] == -1) { // set error code ERRNO = OUT_OF_MEMORY; } freelist[7]->in_use = 0; freelist[7]->size = SBRK_SIZE; freelist[7]->next = NULL; freelist[7]->prev = NULL; heap = freelist[7]; }
void* my_malloc(size_t size) { //Checking for correct parameter int checkSize = size; if (checkSize <= 0) { return NULL; } int currentSize = 16; //We start with the smallest size and move up until we find the first block size that //fits our requirement int index = 0; //Also keep track of an index which tells us which index of the free list corresponds to our block size int adjustedSize = size + sizeof(metadata_t); //We need to add the size of the metadata to the size required by the user to account for the overhead //Checking for error conditions if (size <= 0) { return NULL; } if (adjustedSize > SBRK_SIZE) { ERRNO = SINGLE_REQUEST_TOO_LARGE; return NULL; } while (currentSize < adjustedSize) { currentSize = currentSize*2; index++; //keeping doubling the size of the block until I find the first fit and also increment the //index to keep it consistent with the free list } //if we don't have the block of the required size to give then, start from the index we are at //then we keep going down to bigger block sizes until we get a block which is available to be used if (freelist[index] == NULL) { int n = index; while (n < FREELIST_SIZE && freelist[n] == NULL) { n++; } if (n >= FREELIST_SIZE) { metadata_t* brkPtr = my_sbrk(SBRK_SIZE); if (brkPtr == NULL) { //If the call to my_sbrk returns NULL then we have reached the out of memory condition ERRNO = OUT_OF_MEMORY; return NULL; } if (heap == NULL) { heap = brkPtr; //Setting the heap pointer to point to the beginning of the current heap space //NOTE THAT ONLY THE FIRST CALL TO MALLOC RETURNS THE BEGINNING OF THE HEAP } freelist[7] = brkPtr; freelist[7]->size = SBRK_SIZE; freelist[7]->in_use = 0; freelist[7]->next = NULL; freelist[7]->prev = NULL; } else { split_memBlock(freelist[n], n); //We found the block of smallest size that can be used so we split it //and we send the split blocks to the index which is one less } return my_malloc(size); } else { //get the first available block from the freelist to give to the user metadata_t* give_to_user = freelist[index]; remove_freelist_top(give_to_user, index); give_to_user->in_use = 1; give_to_user->next = NULL; give_to_user->prev = NULL; give_to_user++; //skip over the metadata and get that pointer to the free space ERRNO = NO_ERROR; //return the pointer that comes after skipping over the metadata portion of the block return give_to_user; } }