This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Simple Malloc & Free Functions Submitted by

I've written my own PORTABLE C (how portable i don't know) alloc functions. These routines are very simple, and don't tend to be fast or superior. The idea was to keep the source file small at the begining of development, and later to add new stuff - you know milestones coming - and the lesser stuff more stable it is. So that's the general idea. I'm searching for an article I read one or two years ago from DDJ magazine - it was about a very efficient C/C++ memory manager for Micro- controllers - there was some cute idea about grouping different memory allocations by size. Something like this. If somebody finds any bugs (not design flaws or blah-blah) - please let me know... I'm still testing it... and I've got things running with it... Hope it helps somebody, and I hope somebody helps me with some better code....

Download Associated File: msys.c (2,235 bytes)

    #define USED 1

    typedef struct {
      unsigned size;
    } UNIT;

    typedef struct {
      UNIT* free;
      UNIT* heap;
    } MSYS;

    static MSYS msys;

    static UNIT* compact( UNIT *p, unsigned nsize )
    {
           unsigned bsize, psize;
           UNIT *best;

           best = p;
           bsize = 0;

           while( psize = p->size, psize )
           {
                  if( psize & USED )
                  {
                      if( bsize != 0 )
                      {
                          best->size = bsize;
                          if( bsize >= nsize )
                          {
                              return best;
                          }
                      }
                      bsize = 0;
                      best = p = (UNIT *)( (unsigned)p + (psize & ~USED) );
                  }
                  else
                  {
                      bsize += psize;
                      p = (UNIT *)( (unsigned)p + psize );
                  }
           }

           if( bsize != 0 )
           {
               best->size = bsize;
               if( bsize >= nsize )
               {
                   return best;
               }
           }

           return 0;
    }

    void MSYS_Free( void *ptr )
    {
         if( ptr )
         {
             UNIT *p;

             p = (UNIT *)( (unsigned)ptr - sizeof(UNIT) );
             p->size &= ~USED;
         }
    }

    void *MSYS_Alloc( unsigned size )
    {
         unsigned fsize;
         UNIT *p;

         if( size == 0 ) return 0;

         size  += 3 + sizeof(UNIT);
         size >>= 2;
         size <<= 2;

         if( msys.free == 0 || size > msys.free->size )
         {
             msys.free = compact( msys.heap, size );
             if( msys.free == 0 ) return 0;
         }

         p = msys.free;
         fsize = msys.free->size;

         if( fsize >= size + sizeof(UNIT) )
         {
             msys.free = (UNIT *)( (unsigned)p + size );
             msys.free->size = fsize - size;
         }
         else
         {
             msys.free = 0;
             size = fsize;
         }

         p->size = size | USED;

         return (void *)( (unsigned)p + sizeof(UNIT) );
    }

    void MSYS_Init( void *heap, unsigned len )
    {
         len  += 3;
         len >>= 2;
         len <<= 2;
         msys.free = msys.heap = (UNIT *) heap;
         msys.free->size = msys.heap->size = len - sizeof(UNIT);
         *(unsigned *)((char *)heap + len - 4) = 0;
    }

    void MSYS_Compact( void )
    {
         msys.free = compact( msys.heap, 0x7FFFFFFF );
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.