home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / DLIBSSRC.ZIP / REALLOC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1987-10-10  |  2.2 KB  |  84 lines

  1. #include <stdio.h>
  2. #include <malloc.h>
  3.  
  4. #define    MAXBLK        16
  5. #define    FREE        0x00
  6. #define    USED        0x80
  7. #define    NULLBLK        0x80000000L
  8.  
  9. extern    char    *_mblk[];        /* memory heap pointers */
  10. extern    long    _msiz[];        /* memory heap sizes */
  11.  
  12. static long *unlinkblk(addr)
  13. register long *addr;
  14. /*
  15.  *    Unlink memory block at <addr> from free memory chain.
  16.  */
  17. {
  18.     register int i;
  19.     register long *p, *q;
  20.  
  21.     for(i=0; i<MAXBLK; ++i) {
  22.         if((q = p = _mblk[i]) == NULL)
  23.             continue;        /* skip unavailable blocks */
  24.         if((addr < p) || (addr > ((char *) p)+_msiz[i]))
  25.             continue;        /* block range check */
  26.         while(p = *q) {
  27.             if(p == addr) {        /* found the right block */
  28.                 q[0] = p[1];    /* unlink it */
  29.                 return(p);
  30.             }
  31.             q = p + 1;
  32.         }
  33.     }
  34.     return(NULL);
  35. }
  36.  
  37. char *realloc(addr, size)
  38. register long *addr;
  39. unsigned int size;
  40. /*
  41.  *    Attempt to change the memory block at <addr> to the new <size>.
  42.  *    Making a block smaller will always work, but making it larger
  43.  *    may fail if there is not enough free memory.  If there is not
  44.  *    enough memory, NULL is returned and the block will still reside
  45.  *    at <addr>.  If realloc() succeeds, a pointer to the (possibly
  46.  *    moved) new block will be returned.
  47.  */
  48. {
  49.     register long n, m, d, *p, *q;
  50.     char *lalloc();
  51.  
  52.     p = addr - 1;
  53.     n = p[0] & 0x00FFFFFFL;            /* get actual block size */
  54.     m = (((long) size) + 5L) & ~1L;        /* calculate new block size */
  55.     if(m <= n) {            /* shrink... */
  56.         if((n -= m) >= 8L) {        /* big enough to shrink */
  57.             q = ((char *) p) + m;    /* calculate new break */
  58.             p[0] = m;
  59.             *((char *) p) = USED;
  60.             q[0] = n;
  61.             *((char *) q) = USED;
  62.             free(q + 1);        /* free remainder */
  63.         }
  64.     }
  65.     else {                /* grow... */
  66.         d = *(q = ((char *) p) + n);
  67.         if((d > 0) &&            /* next block is free */
  68.            (m <= (n + d)) &&        /* combination is big enough */
  69.            (unlinkblk(q))) {        /* block can be unlinked */
  70.             p[0] = (n + d);
  71.             *((char *) p) = USED;    /* extend in place */
  72.             return(realloc(addr, size));
  73.         }
  74.         if(p = lalloc(m - 4L)) {    /* allocate bigger block */
  75.             lblkcpy(p, addr, n-4L);    /* copy old data */
  76.             free(addr);        /* free old block */
  77.             addr = p;
  78.         }
  79.         else
  80.             addr = NULL;
  81.     }
  82.     return(addr);
  83. }
  84.