#include #include #include typedef struct Ptr *Ptr; typedef struct Ref *Ref; typedef struct Ptr { Ref ref; Ptr next, prev; } *Ptr; typedef struct Ref { int *data; Ptr head, tail; } *Ref; Ref ref_new(int value) { Ref result = malloc(sizeof(struct Ref)); result->data = malloc(sizeof(int)); *result->data = value; result->head = result->tail = NULL; return result; } Ref ref_move(Ref ref) { Ref result = malloc(sizeof(struct Ref)); result->data = ref->data; result->head = ref->head; result->tail = ref->tail; for (Ptr p = ref->head; p != NULL; p = p->next) { p->ref = result; } free(ref); return result; } void ref_add_ptr(Ref ref, Ptr ptr) { if (ref->head == NULL) { ref->head = ptr; ref->tail = ptr; ptr->next = ptr->prev = NULL; return; } ref->tail->next = ptr; ptr->prev = ref->tail; ptr->next = NULL; ref->tail = ptr; } void ref_remove_ptr(Ref ref, Ptr ptr) { for (Ptr p = ref->head; p != NULL; p = p->next) { if (p == ptr) { if (p->prev == NULL) ref->head = p->next; else p->prev->next = p->next; if (p->next == NULL) ref->tail = p->prev; else p->next->prev = p->prev; return; } } } void ref_free(Ref ref) { for (Ptr p = ref->head; p != NULL; p = p->next) { p->ref = NULL; } free(ref->data); free(ref); } Ptr ptr_new(Ref ref) { Ptr result = malloc(sizeof(struct Ptr)); result->ref = ref; ref_add_ptr(ref, result); return result; } int ptr_get(Ptr ptr) { if (ptr->ref != NULL) return *ptr->ref->data; return 0; } void ptr_free(Ptr ptr) { if (ptr->ref != NULL) ref_remove_ptr(ptr->ref, ptr); free(ptr); } void test_ref() { Ref r1 = ref_new(123); Ptr p1 = ptr_new(r1); Ptr p2 = ptr_new(r1); Ptr p3 = ptr_new(r1); Ptr p4 = ptr_new(r1); Ref r2 = ref_move(r1); int i = ptr_get(p1) + ptr_get(p2) + ptr_get(p3) + ptr_get(p4); ptr_free(p1); ptr_free(p2); ref_free(r2); ptr_free(p3); ptr_free(p4); } void test_reg() { int *r1 = malloc(sizeof(int)); *r1 = 123; int *p1 = r1; int *p2 = r1; int *p3 = r1; int *p4 = r1; int i = *p1 + *p2 + *p3 + *p4; int *r2 = r1; r1 = NULL; free(r2); } int main(int argc, char **argv) { const long N = 1000000; clock_t start, end; start = clock(); for (long i = 0; i < N; i++) test_ref(); end = clock(); printf("ref: %fms\n", ((double)(end - start)) / CLOCKS_PER_SEC * 1000); start = clock(); for (long i = 0; i < N; i++) test_reg(); end = clock(); printf("reg: %fms\n", ((double)(end - start)) / CLOCKS_PER_SEC * 1000); return 0; }