共用体で作るポインタリスト
共用体を使ってポインタのコレクションが作れます。ポインタのサイズ(sizeof(struct Struct*)とsizeof(union PtrList*))が同じだからサイズ的にはok。(struct Struct**)の変数を(union PtrList*)にキャストできるのが新鮮でした。フィールド名を通して元の型に戻せます。
#include <assert.h> #include <stdio.h> #include <stdlib.h> struct Struct { int c; }; union PtrList { union PtrList* next; struct Struct* s; }; struct Struct* state(int c) { struct Struct* s = malloc(sizeof(struct Struct)); s->c = c; return s; } void append(union PtrList* l1, union PtrList* l2) { union PtrList* head_ptr = l1; while(l1->next) l1 = l1->next; assert(NULL == l1->next); l1->next = l2; l1 = head_ptr; } union PtrList* ptr_list(struct Struct** s) { union PtrList* list = (union PtrList*)s; assert(list->next == NULL); return list; } int main(void) { struct Struct *s1, *s2, *s3, *s4; s1 = NULL;s2 = NULL;s3 = NULL;s4 = state('a'); union PtrList *l1, *l2, *l3; l1 = ptr_list(&s1); l2 = ptr_list(&s2); l3 = ptr_list(&s3); union PtrList* l4; //l4->s = s1;//これだと動かない l4 = (union PtrList*)&s4; assert('a' == l4->s->c); append(l1, l2); append(l1, l3); union PtrList* next; int i = 0; for(; l1; l1 = next) { next = l1->next; l1->s = s4; i++; } assert(3 == i); assert(NULL == l1); assert('a' == s1->c); assert('a' == s2->c); assert('a' == s3->c); free(s4); return 0; }