making your own malloc function in C

前端 未结 4 2140
你的背包
你的背包 2021-01-03 09:01

I need your help in this. I have an average knowledge of C and here is the problem. I am about to use some benchmarks to test some computer architecture stuff (branch misses

4条回答
  •  长情又很酷
    2021-01-03 10:00

    I am sharing the complete approach for Malloc and free it works on every scenario. This is complimented using array. We can also implement using link list for metadata.

    There are three Scenarios We have to Cover

    1. Continuous Memory allocation: Allocate memory in continuous manner
    2. Allocated memory between two allocated memory: When Memory is free to allocate in between two allocated memory block. we have to use that memory chunk for allocation.
    3. Allocated from Initial block When Initial block is free.

    for detailed You can see in diagram. Diagram for allocating algo of memory

    Source code for malloc

    #define TRUE        1
    #define FALSE       0
    
    #define MAX_ALOCATION_ALLOWED       20
    static unsigned char our_memory[1024 * 1024];
    
    static int g_allocted_number = 0;
    static int g_heap_base_address = 0;
    
    typedef struct malloc_info
    {
        int address;
        int size;
    }malloc_info_t;
    
    malloc_info_t   metadata_info[MAX_ALOCATION_ALLOWED] ={0};
    
    void* my_malloc(int size)
    {
        int j =0;
        int index = 0 ;
        int initial_gap =0;
        int gap =0;
        int flag = FALSE;
        int initial_flag = FALSE;
        void *address = NULL;
        int heap_index = 0;
        malloc_info_t temp_info = {0};
    
        if(g_allocted_number >= MAX_ALOCATION_ALLOWED)
        {
            return NULL;
        }
    
        for(index = 0; index < g_allocted_number; index++)
        {
            if(metadata_info[index+1].address != 0 )
            {
                initial_gap = metadata_info[0].address - g_heap_base_address; /*Checked Initial Block (Case 3)*/
                if(initial_gap >= size)
                {
                    initial_flag = TRUE;
                    break;
                }
                else
                {
                    gap = metadata_info[index+1].address - (metadata_info[index].address + metadata_info[index].size);  /*Check Gap Between two allocated memory (Case 2)*/
                    if(gap >= size)
                    {
                        flag = TRUE;
                        break;
                    }
                }
            }
        }
    
        if(flag == TRUE)    /*Get Index for allocating memory for case 2*/
        {
            heap_index = ((metadata_info[index].address + metadata_info[index].size) - g_heap_base_address);
        
            for(j = MAX_ALOCATION_ALLOWED -1; j > index+1; j--)
            {
                memcpy(&metadata_info[j], &metadata_info[j-1], sizeof(malloc_info_t));
            }
        }
        else if (initial_flag == TRUE) /*Get Index for allocating memory for case 3*/
        {
            heap_index = 0;
            for(j = MAX_ALOCATION_ALLOWED -1; j > index+1; j--)
            {
                memcpy(&metadata_info[j], &metadata_info[j-1], sizeof(malloc_info_t));
            }
        }
        else /*Get Index for allocating memory for case 1*/
        {
            if(g_allocted_number != 0)
            {
                heap_index = ((metadata_info[index -1].address + metadata_info[index-1].size) - g_heap_base_address);
            }
            else    /* 0 th Location of Metadata for First time allocation*/
                heap_index = 0;
        }
    
        address = &our_memory[heap_index];
        metadata_info[index].address = g_heap_base_address + heap_index;
        metadata_info[index].size = size;
    
        g_allocted_number += 1;
        return address;
    }
    

    Now Code for Free

    void my_free(int address)
    {
        int i =0;
        int copy_meta_data = FALSE;
        
        for(i = 0; i < g_allocted_number; i++)
        {
            if(address == metadata_info[i].address)
            {
                // memset(&our_memory[metadata_info[i].address], 0, metadata_info[i].size);
                g_allocted_number -= 1;
                copy_meta_data = TRUE;
                printf("g_allocted_number in free = %d %d\n", g_allocted_number, address);
                break;
            }
        }
        
        if(copy_meta_data == TRUE)
        {
            if(i == MAX_ALOCATION_ALLOWED -1)
            {
                metadata_info[i].address = 0;
                metadata_info[i].size = 0;
            }
            else
                memcpy(&metadata_info[i], &metadata_info[i+1], sizeof(malloc_info_t));
        }
    }
    

    For testing Now Test code is

    int main()
    {
        int *ptr =NULL;
        int *ptr1 =NULL;
        int *ptr2 =NULL;
        int *ptr3 =NULL;
        int *ptr4 =NULL;
        int *ptr5 =NULL;
        int *ptr6 =NULL;
        
        g_heap_base_address = &our_memory[0];
    
        ptr = my_malloc(20);
        ptr1 = my_malloc(20);
        ptr2 = my_malloc(20);
        
        my_free(ptr);
        ptr3 = my_malloc(10);
        ptr4 = my_malloc(20);
        ptr5 = my_malloc(20);
        ptr6 = my_malloc(10);
        
        printf("Addresses are: %d, %d, %d, %d, %d, %d, %d\n", ptr, ptr1, ptr2, ptr3, ptr4, ptr5, ptr6);
    
        return 0;
    }
    

提交回复
热议问题