Entry

プログラミングメモ - 構造体を使わずにプリミティブ型をまとめる

2009年04月17日

ちょっと前に「qune: プログラミングメモ - 構造体でプリミティブ型をラップする」てのを書いたんですけど,某所でいちいち型名を表す構造体を作るのは面倒だ,とか言われちゃいました。つことで,ラップしないものも書いてみた。

#include <stdio.h>
#include <stdlib.h>

typedef enum TYPE_ {
    INTEGER
} TYPE;

typedef struct HEAD_ {
    TYPE type;
    size_t size;
} HEAD;

int*
create_integer(int a) {
    int* n = 0;
    char* head = (char*)malloc(sizeof(HEAD) + sizeof(int));
    if (head != 0) {
        ((HEAD*)head)->type = INTEGER;
        ((HEAD*)head)->size = sizeof(int);
        n = (int*)(head + sizeof(HEAD));
        *n = a;
    }
    return n;
}

void
free_object(void* ptr) {
    char* p;
    if (ptr != 0) {
        p = ((char*)ptr) - sizeof(HEAD);
        free(p);
    }
}

int
main(int argc, char* argv[]) {
    int* i = create_integer(257);
    if (i != 0) {
        printf("i = %d\n", *i);
        free_object(i);
    }
    return 0;
}

相変わらずポインタで受け取らなきゃいけないんですけど,int* は int* のまま使えます。ポイントは,確保するメモリの手前に,ヘッダを置くことです。もらったアドレスを sizeof(HEAD) バイト分進めると実体を取り出せて,反対に,実体のあるアドレスから,sizeof(HEAD) バイト分減らすと,HEAD* でキャストできるようになります。配列に収めるときは,HEAD*[] な配列に収められる,と。

こゆやり方って,メモリ管理の手法ではよく使われてたりします。確保したメモリのヘッダに次に確保したメモリのアドレスをつけといて,線形リストで管理する。

ま,キャストしまくりなので,普通に使うには危険きわまりないわけですが。ちゃんとしたフレームワークにすれば,もちっと使いやすくなるのかな。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN