Showing posts with label Memory. Show all posts
Showing posts with label Memory. Show all posts

Thursday, August 5, 2010

Custom malloc function Implementation in C

For embedded systems we can't use the standard library functions as it is , since they consume more memory cycles as well as space. So we need to devise our own functions for such purposes.
One similar implementation of memory allocation function 'malloc' is presented here.

#include <stdio.h>
#include <string.h>



typedef
struct
{
    int is_available;
    int size;
} MCB, *MCB_P;


char *mem_start_p;
int max_mem;
int allocated_mem; /* this is the memory in use. */
int mcb_count;

char *heap_end;

MCB_P memallocate(MCB_P ,int );

enum {NEW_MCB=0,NO_MCB,REUSE_MCB};
enum {FREE,IN_USE};
void
InitMem(char *ptr, int size_in_bytes)
{
    /* store the ptr and size_in_bytes in global variable */

    max_mem = size_in_bytes;
    mem_start_p = ptr;
    mcb_count = 0;
    allocated_mem = 0;
    heap_end = mem_start_p + size_in_bytes;
    /* This function is complete :-) */

}


void *
myalloc(int elem_size)
{
    /* check whether any chunk (allocated before) is free first */

    MCB_P p_mcb;
    int flag = NO_MCB;

    p_mcb = (MCB_P)mem_start_p;

    int sz;

    sz = sizeof(MCB);

    if( (elem_size + sz)  > (max_mem - (allocated_mem + mcb_count * sz ) ) )
    {
        printf("Max size Excedded!!!!!");
        return NULL;
    }
    while( heap_end > ( (char *)p_mcb + elem_size + sz)   )
    {

        if ( p_mcb->is_available == 0)
        {

            if( p_mcb->size == 0)
            {
                flag = NEW_MCB;
                break;
            }
            if( p_mcb->size > (elem_size + sz) )
            {
                flag = REUSE_MCB;
                break;
            }
        }
        p_mcb = (MCB_P) ( (char *)p_mcb + p_mcb->size);


    }

    if( flag != NO_MCB)
    {
        p_mcb->is_available = 1;

        if( flag == NEW_MCB)
        {
            p_mcb->size = elem_size + sizeof(MCB);
            mcb_count++;
        }
        allocated_mem += elem_size;
        return ( (char *) p_mcb + sz);
    }

    printf(" Returning as we could not allocate any MCB \n");
    return NULL;


    /* if size of the available chunk is equal to greater than required size, use that chunk */


}

int
MemEfficiency()
{
    /* keep track of number of MCBs in a global variable */
    return mcb_count;
    /* This function is complete as well. :-) */

}

void
myfree(void *p)
{
    /* Mark in MCB that this chunk is free */
    MCB_P ptr = (MCB_P)p;
    ptr--;

    mcb_count--;
    ptr->is_available = FREE;
    printf("\nAllocated mem: %d ",ptr->size);
    allocated_mem -= (ptr->size - sizeof(MCB));
    printf("\nAllocated mem: %d ",allocated_mem);
    printf("\nMemory Freed...");
}

int main()
{
    char buf[1024];
    memset(buf,0,1024);

    InitMem(buf,1024);

    char *str,*str1;

    str=myalloc(100);
    printf("\nMemory address: %p",str);
    printf("\nMCB count: %-3d \tAllocated Memory: %-10d",mcb_count,allocated_mem);
    myfree(str);
    str1=myalloc(200);
    printf("\n\nMemory address: %p",str1);
    printf("\nMCB count: %-3d \tAllocated Memory: %-10d\n",mcb_count,allocated_mem);
}