Home
       realloc.c - scc - simple c99 compiler
  HTML git clone git://git.simple-cc.org/scc
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       realloc.c (1333B)
       ---
            1 #include <errno.h>
            2 #include <stdint.h>
            3 #include <stdlib.h>
            4 #include <string.h>
            5 
            6 #include "malloc.h"
            7 #undef realloc
            8 
            9 void *
           10 realloc(void *ptr, size_t nbytes)
           11 {
           12         Header *oh, *prev, *next, *new;
           13         size_t nunits, avail, onbytes, n;
           14 
           15         if (nbytes == 0) {
           16                 errno = EINVAL;
           17                 return NULL;
           18         }
           19 
           20         if (nbytes > SIZE_MAX - sizeof(Header)-1) {
           21                 errno = ENOMEM;
           22                 return NULL;
           23         }
           24 
           25         if (!ptr)
           26                 return malloc(nbytes);
           27 
           28         nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1;
           29         oh = (Header *) ptr - 1;
           30 
           31         if (oh->h.size == nunits)
           32                 return ptr;
           33 
           34         new = oh + nunits;
           35 
           36         if (nunits < oh->h.size) {
           37                 new->h.size = oh->h.size - nunits;
           38                 oh->h.size = nunits;
           39                 free(new + 1);
           40                 return ptr;
           41         }
           42 
           43         prev = _prevchunk(oh);
           44         next = prev->h.next;
           45 
           46         if (oh + oh->h.size == next) {
           47                 /*
           48                  * if there is free space adjacent
           49                  * to the current memory
           50                  */
           51                 avail = oh->h.size + next->h.size;
           52 
           53                 if (avail == nunits) {
           54                         oh->h.size = nunits;
           55                         prev->h.next = next->h.next;
           56                         _freep = prev;
           57                         return ptr;
           58                 }
           59 
           60                 if (nunits < avail) {
           61                         oh->h.size = nunits;
           62                         prev->h.next = new;
           63                         new->h.next = next->h.next;
           64                         new->h.size = avail - nunits;
           65                         _freep = new;
           66                         return ptr;
           67                 }
           68         }
           69 
           70         if ((new = malloc(nbytes)) == NULL)
           71                 return NULL;
           72 
           73         n = (oh->h.size - 1) * sizeof(Header);
           74         if (n > nbytes)
           75                 n = nbytes;
           76         memcpy(new, ptr, n);
           77         free(ptr);
           78 
           79         return new;
           80 }