2013年9月12日木曜日

開発環境

プログラミング言語C 第2版 ANSI規格準拠 (B.W. カーニハン D.M. リッチー (著)、 石田 晴久 (翻訳)、共立出版)の第8章(UNIXシステム・インタフェース)、8.6(例 - 記憶割当て)、演習8-7を解いてみる。

その他参考書籍

演習 8-7.

コード

sample.c

#include <stdio.h>

int main(int artc, char *argv[])
{
    return 0;
}

#include <unistd.h>

typedef long Align;

union header {
    struct {
        union header *ptr;
        unsigned size;
    } s;
    Align x;
};

typedef union header Header;

/* システムに適した値が分からないのでとりあえず10240に */
#define MAXBYTES (unsigned) 10240

static unsigned maxalloc;
static Header base;
static Header *freep = NULL;

void *malloc(unsigned long nbytes)
{
    Header *p, *prevp;
    Header *morecore(unsigned);
    unsigned nunits;
    
    if (nbytes > MAXBYTES) {
        fprintf(stderr, "can't allocate more than %u bytes\n", MAXBYTES);
        return NULL;
    }
    nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
    if ((prevp = freep) == NULL) {
        base.s.ptr = 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) {
                if (p->s.size == nunits) {
                    prevp->s.ptr = p->s.ptr;
                } else {
                    p->s.size -= nunits;
                    p += p->s.size;
                    p->s.size = nunits;
                }
            }
            freep = prevp;
            return (void *)(p + 1);
        }
        if (p == freep) {
            if ((p = morecore(nunits)) == NULL) {
                return NULL;
            }
        }
    }
}

#define NALLOC 1024

static Header *morecore(unsigned nu)
{
    char *cp;
    void *sbrk(int);
    Header *up;
    void free(void *ap);
    
    if (nu < NALLOC) {
        nu = NALLOC;
    }
    cp = sbrk(nu * sizeof(Header));
    if (cp == (char *) - 1) {
        return NULL;
    }
    up = (Header *) cp;
    up->s.size = nu;
    maxalloc = (up->s.size > maxalloc) ? up->s.size : maxalloc;
    free((void *)(up + 1));
    return freep;
}

void free(void *ap)
{
    Header *bp, *p;
    
    bp = (Header *)ap - 1;
    if (bp->s.size == 0 || bp->s.size > maxalloc) {
        fprintf(stderr, "can't free %u units\n", bp->s.size);
    }
    for (p = 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;
    }
    freep = p;
}

入出力結果(Terminal)

$ cc sample.c
$

とりあえずコンパイルできた。

0 コメント:

コメントを投稿