にたまごほうれん草アーカイブ

はてなダイアリーで書いてた「にたまごほうれん草」という日記のアーカイブです。現在は「にたまごほうれん草ブログ」を運営中です。

擬似malloc続き

擬似mallocを作ってみるの続きです。
リングバッファの要領で(というかまんまリングバッファ)、ついつい入れてしまったmallocをあとから置き換えるためのmallocモドキを改良(?)してみました。
もちろんこんなのがmallocの完全な置き換えにはなるはずもないですが、

  • 取り出すデータのサイズ(構造体)は常に同じ
  • データは、確保された順に開放される

ってこれまんまキューじゃないですか、ただのFIFOじゃないですか、という突っ込みは置いといて。
やってることは、固定サイズの構造体の配列を一定数予め確保して連結リストにしておき、読み出しポインタと戻しポインタがおっかけっこする感じ。この方法だと、同時に確保できるデータは、配列要素数-1個となる。(そういや排他制御もきっちりやらないといけない)

コード

#include <stdio.h>
#define ARRAY_MAX 5

typedef struct _hoge_ { /* 逐次取り出したいデータの構造体 */
    int hoge;
} Hoge;

typedef struct _cell_ { /* データを格納するための連結リストのセル */
    Hoge item;
    struct _cell_ *next;
} Cell;

static Cell buffers[ARRAY_MAX];
static Cell *mallocp = &buffers[0]; /* 取り出すときに進めるポインタ */
static Cell *freep   = &buffers[0]; /* 戻すときに進めるポインタ     */
static int  init  = 0;

void hoge_init()
{
    int i;
    for (i=0; i<ARRAY_MAX; i++) {
        buffers[i].next = &buffers[(i+1)%ARRAY_MAX];
    }
}

void* hoge_malloc(size_t size)
{
    /* 構造体決めうちなので引数なんて無視 */
    Cell *ret;

    if (init == 0) { /* 最初だけ初期化 */
        hoge_init();
        init = 1;
    }

    if (mallocp->next == freep) {
        /* これ以上ポインタを進められない */
        return NULL;
    }

    ret = mallocp;
    mallocp = mallocp->next;
    
    return (void*)ret;
}

void hoge_free(void* ptr)
{
    if (ptr != mallocp) {
        /* mallocpに追いつかなければ一つ進める */
        printf("i'm free!: %d\n", (int)freep);
        freep = freep->next;
    }
    return;
}

#define HOGE_MAX 10
int main(int argc, char* argv[])
{
    int i;
    Hoge *hoges[HOGE_MAX];
    
    for (i=0; i<HOGE_MAX; i++) {/* 初期化 */
        hoges[i] = NULL;
    }

    i = 0;
    while (1) {
        hoges[i] = (Hoge*)hoge_malloc(sizeof(Hoge));
        if (hoges[i] == NULL) {
            fprintf(stdout, "malloc error: %d\n", i);
            break;
        }
        fprintf(stdout, "allocated: %d\n", (int)hoges[i]);
        i++;
    }

    for (i=0; i<HOGE_MAX && hoges[i]!=NULL; i++) {
        hoge_free(hoges[i]);
    }

    return 0;
}

実行結果

$ ./nisemalloc2
allocated: 134518752
allocated: 134518760
allocated: 134518768
allocated: 134518776
malloc error: 4
i'm free!: 134518752
i'm free!: 134518760
i'm free!: 134518768
i'm free!: 134518776

結論

最初からmalloc使わないで済むような実装を考えよう。