scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

realloc.c (1175B)


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