realloc.c (1330B)
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 free(ptr); 17 ptr = NULL; 18 } else if (nbytes > SIZE_MAX - sizeof(Header)-1) { 19 errno = ENOMEM; 20 return NULL; 21 } 22 23 if (!ptr) 24 return malloc(nbytes); 25 26 nunits = (nbytes+sizeof(Header)-1)/sizeof(Header) + 1; 27 oh = (Header *) ptr - 1; 28 29 if (oh->h.size == nunits) 30 return ptr; 31 32 new = oh + nunits; 33 34 if (nunits < oh->h.size) { 35 new->h.size = oh->h.size - nunits; 36 oh->h.size = nunits; 37 free(new + 1); 38 return ptr; 39 } 40 41 prev = _prevchunk(oh); 42 next = prev->h.next; 43 44 if (oh + oh->h.size == next) { 45 /* 46 * if there is free space adjacent 47 * to the current memory 48 */ 49 avail = oh->h.size + next->h.size; 50 51 if (avail == nunits) { 52 oh->h.size = nunits; 53 prev->h.next = next->h.next; 54 _freep = prev; 55 return ptr; 56 } 57 58 if (nunits < avail) { 59 oh->h.size = nunits; 60 prev->h.next = new; 61 new->h.next = next->h.next; 62 new->h.size = avail - nunits; 63 _freep = new; 64 return ptr; 65 } 66 } 67 68 if ((new = malloc(nbytes)) == NULL) 69 return NULL; 70 71 n = (oh->h.size - 1) * sizeof(Header); 72 if (n > nbytes) 73 n = nbytes; 74 memcpy(new, ptr, n); 75 free(ptr); 76 77 return new; 78 }