Listing 5

/* free function */
#include "xalloc.h"

void (free)(void *ptr)
       {       /* free an allocated data object */
       _Cell *q;
       
       if (ptr == NULL)
              return;
       q = (_Cell *)((char *)ptr - CELL_OFF);
       if (q->_Size & _MEMBND)
              return; /* bad pointer */
       if (_Aldata._Head == NULL
              || q < _Aldata._Head)
              {       /* insert at head of list */
              q->_Next = _Aldata._Head;
              _Aldata._Head = q;
              }
       else
              {       /* scan for insertion point */
              _Cell *qp;
              char *qpp;
              
              for (qp = _Aldata._Head;
                     q->_Next && q < qp->_Next; )
                     qp - qp->_Next;
              qpp = (char *)qp + CELL_OFF + qp->_Size;
              if ((char *)q < qpp)
                     return; /* erroneous call */
              else if ((char *)q == qpp)
                     {       /* merge qp and q */
                     qp->_Size += CELL_OFF + q->_Size;
                     q = qp;
                     }
              else
                     {       /* splice q after qp */
                     q->_Next = qp->_Next;
                     qp->_Next = q;
                     }
              }
       if (q->_Next &&
              (char *)q + CELL_OFF + q->_Size == (char *)q->_Next)
              {       /* merge q and q->_Next */
              q->_Size += CELL_OFF + q->_Next->_Size;
              q->_Next = q->_Next->_Next;
              }
       _Aldata._Plast = &q->_Next;    /* resume scan after freed */
       }

/* End of File */