#ifndef SBCLIB_MEM1 // Memory-handing level 1. (Stephen Brooks 2003) // Just handles linear arrays with a kind of "heap scoping". // Best used for keeping track of 'long term' variables, as malloc+free is faster inside loops. // Also no sorting of the array is done, so memfree very slow. #include enum DType {Int=0,Float=1,Double=2,Byte=3,Char=4,Struct=-1}; int DTypeSz[]={sizeof(int),sizeof(float),sizeof(double),sizeof(unsigned char),sizeof(char)}; typedef struct {void *a; int size,level; enum DType contains;} MemBlock; LSet memmgr; char memmgrinit=0; int memscopelevel=0; void meminit(void) { if (memmgrinit) return; memmgr=LSet(MemBlock); memmgrinit=1; } void *memalloc(const int n,const enum DType d) { meminit(); MemBlock b; b.size=n*DTypeSz[d]; b.a=malloc(b.size); b.level=memscopelevel; b.contains=d; LSet_add(&memmgr,&b); return b.a; } int *ialloc(const int n) {return (int *)memalloc(n,Int);} float *falloc(const int n) {return (float *)memalloc(n,Float);} double *dalloc(const int n) {return (double *)memalloc(n,Double);} unsigned char *balloc(const int n) {return (unsigned char *)memalloc(n,Byte);} char *challoc(const int n) {return (char *)memalloc(n,Char);} #define salloc(n,T) (T *)salloc_f(n*sizeof(T)) void *salloc_f(const int bytes) { meminit(); MemBlock b; b.a=malloc(bytes); b.size=bytes; b.level=memscopelevel; b.contains=Struct; LSet_add(&memmgr,&b); return b.a; } void scopein(void) {memscopelevel++;} void scopeout(void) { meminit(); MemBlock *a=(MemBlock *)memmgr.a; for (int n=memmgr.m-1;n>=0;n--) if (a[n].level>=memscopelevel) { free(a[n].a); LSet_remove(&memmgr,n); a=(MemBlock *)memmgr.a; } memscopelevel--; } void memfree(const void *x) { meminit(); MemBlock *a=(MemBlock *)memmgr.a; for (int n=memmgr.m-1;n>=0;n--) if (a[n].a==x) { free(x); LSet_remove(&memmgr,n); return; } } #define SBCLIB_MEM1 #endif