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 }