Featured Post

Trie implementation in C

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);
}


Comments

  1. Your code was great , working perfectly...its working on stack right?..thank u a lot...we were in great need!

    ReplyDelete
  2. I've fixed some bugs.
    This is my working sources:


    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;

    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;
    memset(mem_start_p,0x00,max_mem);
    /* 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;
    int sz;

    p_mcb = (MCB_P)mem_start_p;


    sz = sizeof(MCB);

    if( (elem_size + sz) > (max_mem - (allocated_mem + mcb_count * sz ) ) )
    {
    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);
    }
    else if( flag == REUSE_MCB)
    {
    elem_size = p_mcb->size - sizeof(MCB);
    }
    mcb_count++;
    allocated_mem += elem_size;
    return ( (char *) p_mcb + sz);
    }

    return NULL;


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


    }

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

    if(ptr->is_available != FREE)
    {
    mcb_count--;
    ptr->is_available = FREE;
    allocated_mem -= (ptr->size - sizeof(MCB));
    }
    }

    ReplyDelete
  3. how can u say it as dynamic allocation of memory?
    and also its on stack

    ReplyDelete
  4. It is indeed dynamic allocation of memory from available memory block (in this case a buffer of 1024 B). The memory can be freed at runtime and reused. Yes it is working on stack currently , but can be modified to allocate from heap.

    ReplyDelete
    Replies
    1. Hi Varun, my name is Paulo, can you guide me on how to modify to allocate from heap?

      Delete
  5. Hi Shiva.. No this example is not thread safe. But with use of some synchronization and locking mechanisms, it can be made thread safe.

    ReplyDelete
    Replies
    1. Hi Varun, my name is Paulo, can you guide me on how to modify to allocate from heap?

      Delete
  6. Hello)
    typedef
    struct
    {
    int is_available;
    int size;
    } MCB, *MCB_P;
    What means MCB?

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. Hi Varun, my name is Paulo, can you guide me on how to modify to allocate from heap?

    ReplyDelete
    Replies
    1. where exactly you want to allocate from heap ?

      Delete
  9. Just as a comment for others looking at this implementation, it does not appear to consolidate freed blocks at any point. Memory will fragment over time.

    ReplyDelete

Post a Comment

Please post your valuable suggestions