# 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` 運作原理,需要分析程式碼並設計實驗
:::