acl4のページ0002

(1)

#if (a_Version >= 1)
    #define List            a_List
    #define List_ini        a_List_ini
    #define List_addTl      a_List_addTl
    #define List_addHd      a_List_addHd
    #define List_rmv        a_List_rmv
#endif

a_class(a_List) { a_List *prv, *nxt; };
a_static void a_List_ini(a_List *w) { w->prv = w->nxt = w; }

a_static void a_List_add(a_List *prv, a_List *tgt, a_List *nxt)
{
    prv->nxt = tgt;
    tgt->prv = prv;
    tgt->nxt = nxt;
    nxt->prv = tgt;
}

a_static void a_List_rmv(a_List *prv, a_List *nxt) { prv->nxt = nxt; nxt->prv = prv; }
a_static void a_List_addTl(a_List *w, a_List *tgt) { a_List_add(w->prv, tgt, w); }
a_static void a_List_addHd(a_List *w, a_List *tgt) { a_List_add(w, tgt, w->nxt); }

#if (a_Version >= 1)
    #define malloc_     a_malloc
    #define free_       a_free
    #define realloc_    a_realloc
#endif

a_class(a_malloc_Header) {
    a_List lst[1];
    intptr_t dmy[1], sz, lin;
    const char *fil;
    intptr_t serialNum, sig;
};

a_malloc_Header a_malloc_hed0[1];
#define a_malloc_Sig    0xff0055aa

a_static void *a_malloc(_argDef_  intptr_t sz)
{
    #if (a_DbgLv < 2)
        void *p = malloc(sz);
        if (p == NULL)
            a_errExit("malloc_: out of memory: sz=%d");
        return p;
    #else
        if (sz < 0)
            a_errExit("%s(%d): malloc_ size error: sz=%d", a_fil, a_lin, (int) sz);
        a_malloc_Header *h = (a_malloc_Header *) malloc(sz + sizeof (a_malloc_Header));
        if (h == NULL)
            a_errExit("%s(%d): malloc_: out of memory: sz=%d", a_fil, a_lin, (int) sz);
        if (a_malloc_hed0->lst->prv == NULL) {
            a_List_ini(a_malloc_hed0->lst);
            a_malloc_hed0->sz = -1;
            a_malloc_hed0->sig = a_malloc_Sig;
            a_malloc_hed0->lin = 0;
        }
        a_List_addTl(a_malloc_hed0->lst, h->lst);
        h->sz = sz;
        h->sig = a_malloc_Sig;
        h->lin = a_lin;
        h->fil = a_fil;
        h->serialNum = ++(a_malloc_hed0->serialNum);
        a_malloc_hed0->lin++;
        return h + 1;
    #endif
}

a_static void a_free(_argDef_  void *p, intptr_t sz)
{
    #if (a_DbgLv < 2)
        (void) sz;
        free(p);
    #else
        if (p == NULL) return;
        a_malloc_Header *h = (a_malloc_Header *) p - 1;
        if (h->sig != a_malloc_Sig)
            a_errExit("%s(%d): free_: bad signature", a_fil, a_lin);
        if (h->sz != sz)
            a_errExit("%s(%d): free_: bad size: sz=%d, arg=%d", a_fil, a_lin, (int) h->sz, (int) sz);
        h->sig = 0;
        h->serialNum = 0;
        a_List_rmv(h->lst->prv, h->lst->nxt);
        a_malloc_hed0->lin--;
        free(h);
    #endif
}

a_static void *a_realloc(_argDef_  void *p, intptr_t sz0, intptr_t sz1)
{
    #if (a_DbgLv < 2)
        (void) sz0;
        p = realloc(p, sz1);
        if (p == NULL)
            a_errExit("realloc_: out of memory: sz1=%d");
        return p;
    #else
        if (sz1 < 0)
            a_errExit("%s(%d): realloc_ size error: sz1=%d", a_fil, a_lin, (int) sz1); 
        if (p == NULL)
            return a_malloc(a_fil, a_lin, sz1);
        a_malloc_Header *h = (a_malloc_Header *) p - 1;
        if (h->sig != a_malloc_Sig)
            a_errExit("%s(%d): realloc_: bad signature", a_fil, a_lin);
        if (h->sz != sz0)
            a_errExit("%s(%d): realloc_: bad size: sz=%d, arg=%d", a_fil, a_lin, (int) h->sz, (int) sz0);
        h->sig = 0;
        intptr_t sn = h->serialNum;
        h->serialNum = 0;
        a_List *prv = h->lst->prv;
        a_List *nxt = h->lst->nxt;
        a_List_rmv(prv, nxt);
        a_malloc_Header *h1 = (a_malloc_Header *) realloc(h, sz1 + sizeof (a_malloc_Header));
        if (h1 == NULL)
            a_errExit("%s(%d): realloc_: out of memory: sz1=%d", a_fil, a_lin, (int) sz1);
        a_List_add(prv, h1->lst, nxt);
        h1->sig = a_malloc_Sig;
        h1->serialNum = sn;
        h1->sz = sz1;
        h1->lin = a_lin;
        h1->fil = a_fil;
        return h1 + 1;
    #endif
}

a_static intptr_t a_malloc_totalSiz(_argDef_  intptr_t *pn)
{
    intptr_t s = 0;
    #if (a_DbgLv >= 2)
        (void) a_fil; (void) a_lin;
        if (a_malloc_hed0->lst->prv != NULL) {
            a_List *t = a_malloc_hed0->lst->nxt;
            for (;;) {
                a_malloc_Header *h = (a_malloc_Header *) t;
                if (h->sz < 0) break;
                s += h->sz;
                t = t->nxt;
            }
        }
    #endif
    if (pn != NULL) *pn = a_malloc_hed0->lin;
    return s;
}

a_static void a_malloc_debugList(_argDef)
{
    #if (a_DbgLv >= 2)
        fprintf(stderr, "%s(%d): malloc_debugList()\n", a_fil, a_lin);
        if (a_malloc_hed0->lst->prv != NULL) {
            a_List *t = a_malloc_hed0->lst->nxt;
            for (;;) {
                a_malloc_Header *h = (a_malloc_Header *) t;
                if (h->sz < 0) break;
                fprintf(stderr, "  [p:%08x sz:%d / %s(%d)]\n", (int) (intptr_t) (h + 1), h->sz, h->fil, h->lin);
                t = t->nxt;
            }
        }
    #endif
}

(2) List

(3) malloc_, free_, realloc_

(4) 使い方

#define a_Version 1
#include <acl4.c>

int main()
{
    char *p = malloc_(_arg_  12);
    char *q = malloc_(_arg_  34);
    char *r = malloc_(_arg_  56);
    char *s = malloc_(_arg_  78);
    free_(_arg_ q, 34);
    r = realloc_(_arg_  r, 56, 90);
    a_malloc_debugList(_arg);
    return 0;
}
>t0002a
t0002a.c(12): malloc_debugList()
  [p:00d2cb38 sz:12 / t0002a.c(6)]
  [p:00d330e8 sz:90 / t0002a.c(11)]
  [p:00d33070 sz:78 / t0002a.c(9)]

(5)

(99) 更新履歴


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS