# 2019q1 第 4 週測驗題 (上) :::info 目的: 檢驗學員對 C 程式設計的認知 ::: --- ### 測驗 `1` 考慮到以下簡易的 reference counting 實作: ```cpp #include <stdlib.h> #define REF_TYPE(type) ref_to_##type * #define REF_DEFINE(type) \ typedef struct P { \ unsigned c, l; \ type *o; \ } ref_to_##type; \ REF_TYPE(type) ref_new_##type() \ { \ type *o = (type *) malloc(sizeof(type)); \ REF_TYPE(type) r = ((REF_TYPE(type)) malloc(sizeof(ref_to_##type))); \ r->o = o; \ r->c = 0; \ r->l = 0; \ return r; \ } #define ref_new(type) ref_new_##type() #define ref_acquire(ref) \ { \ ref->c++; \ ref->l++; \ } #define ref_release(ref) \ if (Q) { \ free(ref->o); \ free(ref); \ } #define ref_val(ref) R #include <stdio.h> #include <string.h> typedef struct { char hello[32]; long number; } foo; REF_DEFINE(foo); void bar(REF_TYPE(foo) x) { ref_acquire(x); printf("%s\n", ref_val(x).hello); ref_val(x).number = 123; ref_release(x); } int main(int argc, char **argv) { REF_TYPE(foo) x; x = ref_new(foo); ref_acquire(x); strncpy(ref_val(x).hello, "Hello world!", 32); bar(x); printf("%ld\n", ref_val(x).number); printf("\n"); printf("total acquisitions: %d\n", S); printf("current references: %d\n", T); ref_release(x); return 0; } ``` 預期執行輸出如下: ``` Hello world! 123 total acquisitions: 2 current references: 1 ``` 請補完程式碼 ==作答區== P = ? * `(a)` `ref_to_#type#` * `(b)` `ref_to_##type##_s` * `(c)` `ref_to_#type` Q = ? * `(a)` `--ref->c` * `(b)` `--(ref->c)` * `(c)` `(ref->c)--` * `(d)` `!--ref->c` * `(e)` `&--ref->c` R = ? * `(a)` `ref` * `(b)` `*ref` * `(c)` `&ref` * `(d)` `*ref->o` * `(e)` `(*(ref->o))` S = ? * `(a)` `x` * `(b)` `x->o` * `(c)` `x->c` * `(d)` `x->l` T = ? * `(a)` `x` * `(b)` `x->o` * `(c)` `x->c` * `(d)` `x->l` :::success 延伸問題: 1. 在 Linux 核心找出類似的 reference counting 程式碼並解說; 2. 用上述的 reference counting 解釋 `lsmod` 命令輸出的 `Used by` 運作原理,需要分析程式碼並設計實驗 :::