#include <unistd.h>
#include <stdlib.h>
#ifndef _MALLOC_H
#define _MALLOC_H
#define NULL ((void *)0)
typedef long Align;
union header {
struct {
union header *ptr;
unsigned size;
} s;
Align x;
};
typedef union header Header;
void *my_malloc(unsigned nbytes);
static Header *morecore(unsigned nu);
void my_free(void *ap);
void *calloc(unsigned count, unsigned size);
unsigned bfree(void *b, unsigned n);
#endif
#define NALLOC 10
static Header base;
static Header *my_freep = NULL;
void *my_malloc(unsigned nbytes) {
Header *p, *prevp;
Header *morecore(unsigned);
unsigned nunits;
nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
if ((prevp = my_freep) == NULL) {
base.s.ptr = my_freep = prevp = &base;
base.s.size = 0;
}
for (p = prevp->s.ptr;; prevp = p, p = p->s.ptr) {
if (p->s.size >= nunits) {
if (p->s.size == nunits)
prevp->s.ptr = p->s.ptr;
else {
p->s.size -= nunits;
p += p->s.size;
p->s.size = nunits;
}
my_freep = prevp;
return (void*) (p + 1);
}
if (p == my_freep)
if ((p == morecore(nunits)) == NULL)
return NULL;
}
}
Header *morecore(unsigned nu) {
char *cp;
Header *up;
if (nu < NALLOC)
nu = NALLOC;
cp = sbrk(nu * sizeof(Header));
printf("sbrk:%X--%X\n", cp, cp + nu * sizeof(Header));
if (cp == (char *) -1)
return NULL;
up = (Header *) cp;
up->s.size = nu;
my_free((void *) (up + 1));
return my_freep;
}
void printlist(void) {
Header *p;
int i = 0;
printf("base:%X, base.s.ptr:%X, base.s.ptr.ptr:%X\n", &base, base.s.ptr,
base.s.ptr->s.ptr, my_freep);
for (p = &base; p->s.ptr != my_freep; p = p->s.ptr) {
i++;
printf("block[%d],size=%d", i, p->s.size);
if (p > my_freep)
printf("used!\n");
else
printf("my_free!\n");
}
}
void my_free(void *ap) {
Header *bp, *p;
bp = (Header *) ap - 1;
if (bp->s.size <= 0)
return;
for (p = my_freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
break;
if (bp + bp->s.size == p->s.ptr) {
bp->s.size += p->s.ptr->s.size;
bp->s.ptr = p->s.ptr->s.ptr;
} else
bp->s.ptr = p->s.ptr;
if (p + p->s.size == bp) {
p->s.size += bp->s.size;
p->s.ptr = bp->s.ptr;
} else
p->s.ptr = bp;
my_freep = p;
}
int main() {
char *p[30];
int i;
for (i = 0; i < 30; i++) {
p[i] = (char *) my_malloc(8);
printf("my_malloc %d, %X\n", i, p[i]);
printlist();
}
for (i = 29; i >= 0; i--) {
my_free(p[i]);
printf("my_free %d \n", i);
printlist();
}
return 0;
}
void *calloc(unsigned n, unsigned size) {
unsigned nb;
char *p, *q;
nb = n * size;
if ((p = q = my_malloc(nb)) != NULL)
while (p < p + nb)
*p++ = 0;
return (void *) q;
}
unsigned bfree(void *b, unsigned n) {
Header *p, *bp;
if (n < sizeof(Header) + 1)
return 0;
bp = (Header *) b;
bp->s.size = n / sizeof(Header);
my_free((void *) (bp + 1));
return bp->s.size;
}