scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

realloc.c (1160B)


      1 #include <stdlib.h>
      2 #include <string.h>
      3 
      4 #include "malloc.h"
      5 
      6 void *
      7 realloc(void *ptr, size_t nbytes)
      8 {
      9 	Header *oh, *prev, *next, *new;
     10 	size_t nunits, avail, onbytes, n;
     11 
     12 	if (!nbytes)
     13 		return NULL;
     14 
     15 	if (!ptr)
     16 		return malloc(nbytes);
     17 
     18 	nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
     19 	oh = (Header*)ptr - 1;
     20 
     21 	if (oh->h.size == nunits)
     22 		return ptr;
     23 
     24 	new = oh + nunits;
     25 
     26 	if (nunits < oh->h.size - 1) {
     27 		new->h.size = oh->h.size - nunits;
     28 		oh->h.size = nunits;
     29 		free(new + 1);
     30 		return oh;
     31 	}
     32 
     33 	prev = _prevchunk(oh);
     34 
     35 	if (oh + oh->h.size == prev->h.next) {
     36 		/*
     37 		 * if there is free space adjacent
     38 		 * to the current memory
     39 		 */
     40 		next = prev->h.next;
     41 		avail = oh->h.size + next->h.size;
     42 
     43 		if (avail == nunits) {
     44 			oh->h.size = nunits;
     45 			prev->h.next = next->h.next;
     46 			return oh;
     47 		}
     48 
     49 		if (avail > nunits) {
     50 			oh->h.size = nunits;
     51 			prev->h.next = new;
     52 			new->h.next = next;
     53 			new->h.size = avail - nunits;
     54 			return oh;
     55 		}
     56 	}
     57 
     58 	onbytes = (oh->h.size - 1) * sizeof(Header);
     59 	if ((new = malloc(nbytes)) == NULL)
     60 		return NULL;
     61 
     62 	n = (onbytes > nbytes) ? nbytes : onbytes;
     63 	memcpy(new, ptr, n);
     64 	free(ptr);
     65 
     66 	return new;
     67 }