contributed by < yuchun1214
>
注意共筆書寫規範:中英文間用一個半形空白字元區隔
queue中除了遠本的 list_ele_t *head
以外,我還多加了 list_ele_t *tail
用來指向queue的尾端,以及 int size
來紀錄queue的長度。
q_free的功能是將queue清掉。在這裡為了能夠更好的閱讀程式碼,我清掉element的函數另外寫成 void list_ele_free(list_ele_t *ele)
在 insert head 的部分我有點不太滿意自己寫的 code ,主要是底下23行的地放為了能讓 q->tail
能指向正確的位置,但實際上會進入 if 內只會發生在插入第一個 element 時,卻要每次 insert 時都要做 if 的判斷。
由於有天在 queue_t
中添加 tail
因此能夠很輕鬆的將 element 加入 queue 中。
這個函數比較需要注意的是 line 18 ,因為 strncpy
並不會加上 \0
因此要自己加上
這個函數要求要在 內完成。在這個函數裡用了一個operator來做判斷,就程式面上來看應該是 ,但不知為何, make test
量測的結果卻不一定是constant time.於是我決定去看一下組合語言。
從組合語言看起來只差一個 mov
的 instruction
而已,但卻被判斷不一定是常數時間。
實作的原理主要是將每個 element 的 next 指標轉向,指向前一個 element(line:12)
在 q_sort 中原本我有嘗試 quick sort ,但後來想一想會了求穩定還是轉為使用 merge sort ,不過如果實際去看queue.c
還是看得到 quick sort code 。
merge sort中主要分兩部分,分別是 list_merge_sort
以及 list_merge
,前者主要做拆分的動作,後者則是做merge。
總結以上函數有仔細寫大概都可以拿到100分。
在 make SANITIZER=1
並執行qtest help之後可清楚看見一些錯誤的訊息,訊息指出是 do_help_cmd
函數出錯。
但經肉眼檢查發現應該沒什麼問題,因此轉而檢查 add_param
以及呼叫 add_param
的code,發現問題可能是出現在這裏做的將 int*
指向 bool*
的問題,於是加以修改之後就沒問題了
在 make valgrind
後可以看到一系列的錯問訊息指出有記憶體是 unreachable 。
實際去找出錯誤訊息的程式發現是 strdup
在搞鬼
strdup manual
中是這樣寫的:
於是我認為應該是history最後沒有清掉記憶體,但在 static void freeHistory(void)
中卻有寫到。
於是我開始懷疑是否是因為 history
是 global variable 的關係,因而 valgrind 在檢查時是依照函數內容去做檢查,並非全面性的檢查所有的記憶體。 但這部分仍有待確認… 經過確認後發現, valgrind 的行為並非上述所說。原本我的作法是在 .valgrindrc
中加上 --show-reachable=no
,但這方式有點鴕鳥心態,這樣只是假裝看不到錯誤,並非錯誤消失了。在確認 valgrind
的行為後我決定找出原因。在 linenoise.c 中,原開發者的確有寫到 freeHistory 這些程式碼的內容沒錯,關鍵的原因在於當使用 .cmd
檔案當作輸入時,程式完全不會呼叫 freeHistory
。最簡單的解法就是在 console.c:run_console
結束前呼叫 freeHistory
即可。