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 }