# 2020q1 Homework1 (lab0)
contributed by < `jaxbau` >
## :penguin: 作業要求
* 截止日期: Mar 21, 2020 (含) 之前
- [x] 在 GitHub 上 fork [lab0-c](https://github.com/sysprog21/lab0-c)
* 參閱 [Git 教學和 GitHub 設定指引](https://hackmd.io/@sysprog/git-with-github) ^附教學影片^
- [x] 詳細閱讀 [C Programming Lab](http://www.cs.cmu.edu/~213/labs/cprogramminglab.pdf)
- [ ] 依據指示著手修改 `queue.[ch]` 和連帶的檔案,測試後用 Git 管理各項修改,
記得也該實作 `q_sort` 函式。
- [ ] 修改排序所用的比較函式,變更為 [natural sort](https://github.com/sourcefrog/natsort),
在 "simulation" 也該做對應的修改,得以反映出 [natural sort](https://github.com/sourcefrog/natsort) 的使用。
- [ ]也要編輯「[作業區](https://hackmd.io/@sysprog/linux2020-homework1)」,增添開發紀錄和 GitHub 連結
#### 如何逐步達到自動評分程式的要求
#### 運用 Valgrind 排除 `qtest` 實作的記憶體錯誤,並透過 Massif 視覺化 "simulation" 過程中的記憶體使用量,需要設計對應的實驗
>
#### 研讀論文 [Dude, is my code constant time?](https://eprint.iacr.org/2016/1123.pdf),解釋本程式的 "simulation" 模式是如何透過以實驗而非理論分析,達到驗證時間複雜度,需要解釋 [Student's t-distribution](https://en.wikipedia.org/wiki/Student%27s_t-distribution) 及程式實作的原理;
#### 解釋 [select](http://man7.org/linux/man-pages/man2/select.2.html) 系統呼叫在本程式的使用方式,並分析 [console.c](https://github.com/sysprog21/lab0-c/blob/master/console.c) 的實作,說明其中運用 CS:APP [RIO 套件](http://csapp.cs.cmu.edu/2e/ch10-preview.pdf) 的原理和考量點。可對照參考 [CS:APP 第 10 章重點提示](https://hackmd.io/@sysprog/H1TtmVTTz) :arrow_forward: 為避免「舉燭」,請比照 `qtest` 實作,撰寫獨立的終端機命令解譯器 (可建立新的 GitHub repository)
#### 記錄
先把 git 切到 dev 分支再來對程式碼做測試
照老師說的使用 clang-format 後執行 make check 結果跳很多錯誤
```
CC report.o
In file included from report.c:1:
report.h:35:22: error: unknown type name ‘size_t’
35 | void *malloc_or_fail(size_t bytes, char *fun_name);
| ^~~~~~
report.h:6:1: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
5 | #include <stdbool.h>
+++ |+#include <stddef.h>
6 |
report.h:38:22: error: unknown type name ‘size_t’
38 | void *calloc_or_fail(size_t cnt, size_t bytes, char *fun_name);
| ^~~~~~
report.h:38:22: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
report.h:38:34: error: unknown type name ‘size_t’
38 | void *calloc_or_fail(size_t cnt, size_t bytes, char *fun_name);
| ^~~~~~
report.h:38:34: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
report.h:44:26: error: unknown type name ‘size_t’
44 | void free_block(void *b, size_t len);
| ^~~~~~
report.h:44:26: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
report.h:47:26: error: unknown type name ‘size_t’
47 | void free_array(void *b, size_t cnt, size_t bytes);
| ^~~~~~
report.h:47:26: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
report.h:47:38: error: unknown type name ‘size_t’
47 | void free_array(void *b, size_t cnt, size_t bytes);
| ^~~~~~
report.h:47:38: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
make: *** [Makefile:39: report.o] Error 1
```
去查看 clang-format 對我做了什麼好事
```
vim .clang-format
```
```
1 BasedOnStyle: Chromium
2 Language: Cpp
3 MaxEmptyLinesToKeep: 3
4 IndentCaseLabels: false
5 AllowShortIfStatementsOnASingleLine: false
6 AllowShortCaseLabelsOnASingleLine: false
7 AllowShortLoopsOnASingleLine: false
8 DerivePointerAlignment: false
9 PointerAlignment: Right
10 SpaceAfterCStyleCast: true
11 TabWidth: 4
12 UseTab: Never
13 IndentWidth: 4
14 BreakBeforeBraces: Linux
15 AccessModifierOffset: -4
```
其實看不出來是哪條設定去更動 include 順序
直接對 include 順序調動做測試
發現 report.h 在 signal.h 後就不會報錯
先去 report.h 加上 include signal.h 後做測試
```
jax@jax:~/Documents/C/lab0-c$ clang-format -i *.[ch]
jax@jax:~/Documents/C/lab0-c$ make check
CC report.o
LD qtest
./qtest -v 3 -f traces/trace-eg.cmd
cmd>
cmd> # Demonstration of queue testing framework
cmd> # Use help command to see list of commands and options
cmd> # Initial queue is NULL.
cmd> show
q = NULL
cmd> # Create empty queue
cmd> new
q = []
cmd> # Fill it with some values. First at the head
cmd> ih dolphin
q = [Segmentation fault occurred. You dereferenced a NULL or invalid pointer
make: *** [Makefile:42: check] 取消 (core dumped)
```
至少維持在原樣又能用clang-format了
commit
:::spoiler
我不是故意不讀資料,但作業交期快到了
前面好長一段時間都在學 git markdown 跟 c 還是希望能交出一點作業 至少把lab0做完
:::
### 再來是牛刀小試
queue.h
```
typedef struct {
list_ele_t *head; /* Linked list of elements */
int size;
/* TODO: You will need to add more fields to this structure
* to efficiently implement q_size and q_insert_tail.
*/
/* TODO: Remove the above comment when you are about to implement. */
} queue_t;
```
queue.c
```
int q_size(queue_t *q)
{
return q->size;
}
```
```
cmd> new
cmd> new
q = []
cmd> size
cmd> size
ERROR: Computed queue size as 1431655765, but correct value is 0
```
又錯了…
原來在 qnew 還要加上 init 值
queue
```
queue_t *q_new()
{
queue_t *q = malloc(sizeof(queue_t));
/* TODO: What if malloc returned NULL? */
q->head = NULL;
q->size = 0;
return q;
}
```
再make一次並做測試
```
cmd> new
cmd> new
q = []
cmd> size
cmd> size
Queue size = 0
q = []
```
commit
### ih q_insert_head 實做
```
./qtest -v 3 -f traces/trace-eg.cmd
cmd>
cmd> # Demonstration of queue testing framework
cmd> # Use help command to see list of commands and options
cmd> # Initial queue is NULL.
cmd> show
q = NULL
cmd> # Create empty queue
cmd> new
q = []
cmd> # Fill it with some values. First at the head
cmd> ih dolphin
q = [Segmentation fault occurred. You dereferenced a NULL or invalid pointer
make: *** [Makefile:42: check] 取消 (core dumped)
```
輸出可以看到 ih dolphin 會報錯,所以先把ih的部份寫好
修改 queue.c
```
bool q_insert_head(queue_t *q, char *s)
{
list_ele_t *newh;
/* TODO: What should you do if the q is NULL? */
newh = malloc(sizeof(list_ele_t));
newh->value = s;
/* What if either call to malloc returns NULL? */
newh->next = q->head;
q->head = newh;
return true;
}
```
輸出
```
CC queue.o
LD qtest
./qtest -v 3 -f traces/trace-eg.cmd
cmd>
cmd> # Demonstration of queue testing framework
cmd> # Use help command to see list of commands and options
cmd> # Initial queue is NULL.
cmd> show
q = NULL
cmd> # Create empty queue
cmd> new
q = []
cmd> # Fill it with some values. First at the head
cmd> ih dolphin
ERROR: Need to allocate and copy string for new list element
q = [dolphin]
cmd> ih bear
ERROR: Need to allocate and copy string for new list element
q = [bear ih]
...
```
可以看到讀得到字串但有告警說 Need to allocate and copy string for new list element
應該是因為 q_new q->head NULL
```
queue_t *q_new()
{
queue_t *q = malloc(sizeof(queue_t));
/* TODO: What if malloc returned NULL? */
q->head = NULL;
q->size = 0;
return q;
}
```