1 /* 2 simple memory manage demo from TCPL 3 should be compiled in unix 4 debug to see how it works 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 11 typedef long Align; 12 13 union header 14 { 15 struct 16 { 17 union header* ptr; 18 unsigned size; 19 } s; 20 Align x; 21 }; 22 23 typedef union header Header; 24 25 26 static Header base; 27 static Header* freep = NULL; 28 static Header* morecore(unsigned); 29 30 void* malloc(unsigned nbytes) 31 { 32 Header* p; 33 Header* prevp; 34 unsigned nunits; 35 nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1; 36 if ((prevp = freep) == NULL) 37 { 38 base.s.ptr = freep = prevp = &base; 39 base.s.size = 0; 40 } 41 42 for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) 43 { 44 if (p->s.size >= nunits) 45 { 46 if (p->s.size == nunits) 47 prevp->s.ptr = p->s.ptr; 48 else 49 { 50 p->s.size -= nunits; 51 p += p->s.size; 52 p->s.size = nunits; 53 } 54 freep = prevp; 55 56 return (void*)(p + 1); 57 } 58 if (p == freep) 59 if ((p == morecore(nunits)) == NULL) 60 return NULL; 61 } 62 } 63 64 65 #define NALLOC 1024 66 67 static Header* morecore(unsigned nu) 68 { 69 char* cp; 70 Header* up; 71 72 if (nu < NALLOC) 73 nu = NALLOC; 74 cp =(char*) sbrk(nu * sizeof(Header)); 75 if (cp == (char*) - 1) 76 return NULL; 77 up = (Header*)cp; 78 up->s.size = nu; 79 free((void*)(up + 1)); 80 81 return freep; 82 } 83 84 void free(void* ap) 85 { 86 Header* bp; 87 Header* p; 88 89 bp = (Header*)ap - 1; 90 for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr) 91 if (p >= p->s.ptr && (bp > p || bp < p->s.ptr)) 92 break; 93 if (bp + bp->s.size == p->s.ptr) 94 { 95 bp->s.size += p->s.ptr->s.size; 96 bp->s.ptr = p->s.ptr->s.ptr; 97 } 98 else 99 bp->s.ptr = p->s.ptr; 100 101 if (p + p->s.size == bp) 102 { 103 p->s.size += bp->s.size; 104 p->s.ptr = bp->s.ptr; 105 } 106 else 107 p->s.ptr = bp; 108 109 freep = p; 110 } 111 112 int main(int argc, char* argv[]) 113 { 114 char* str; 115 str=malloc(100*sizeof(char)); 116 117 char* str2=malloc(10*sizeof(char)); 118 119 free(str); 120 free(str2); 121 122 return 0; 123 }