contributed by < eric88525
>
queue.[ch]
和連帶的檔案,測試後用 Git 管理各項修改,要能滿足 $ make test
自動評分系統的所有項目。
lab0-c
專案,比較你自己實作的 merge sort 和 Linux 核心程式碼之間效能落差qtest
提供新的命令 shuffle
,允許藉由 Fisher–Yates shuffle 演算法,對佇列中所有節點進行洗牌 (shuffle) 操作qtest
提供新的命令 web
,提供 web 伺服器功能,注意: web 伺服器運作過程中,qtest
仍可接受其他命令
qtest
執行過程中的錯誤
qtest
再於命令提示列輸入 help
命令,會使 開啟 Address Sanitizer 觸發錯誤,應予以排除qtest
實作的記憶體錯誤,並透過 Massif 視覺化 "simulation" 過程中的記憶體使用量,需要設計對應的實驗指示著手修改 queue.[ch] 和連帶的檔案,測試後用 Git 管理各項修改,記得也該實作 q_sort 函式。
queue.c 僅提供介面 (interface) 但尚未有完整程式實作,需要由學員補完並逐步精進,包含以下:
q_new
: 建立新的「空」佇列;q_free
: 釋放佇列所佔用的記憶體;q_insert_head
: 在佇列開頭 (head) 插入 (insert) 給定的新節點 (以 LIFO 準則);q_insert_tail
: 在佇列尾端 (tail) 插入 (insert) 給定的新節點 (以 FIFO 準則);q_ _head
: 在佇列開頭 (head) 移去 (remove) 給定的節點;q_release_element
: 釋放特定節點的記憶體空間;q_size
: 計算目前佇列的節點總量;q_delete_mid
: 移走佇列中間的節點,詳見 LeetCode 2095. Delete the Middle Node of a Linked Listq_delete_dup
: 在已經排序的狀況,移走佇列中具備重複內容的節點,詳見 LeetCode 82. Remove Duplicates from Sorted List IIq_swap
: 交換佇列中鄰近的節點,詳見 LeetCode 24. Swap Nodes in Pairsq_reverse
: 以反向順序重新排列鏈結串列,該函式不該配置或釋放任何鏈結串列節點,換言之,它只能重排已經存在的節點;q_sort
: 以遞增順序來排序鏈結串列的節點,可參閱 Linked List Sort 得知實作手法;建立空的list_head,並閱讀linux kernel api和list.h來簡化相關程式
list_add: Insert a new entry after the specified head. This is good for implementing stacks.
list_add_tail: Insert a new entry before the specified head. This is useful for implementing queues.
參考作業說明 的 qtest 命令直譯器介紹來實作
在 qtest.c 的 console_init()
內加入這行,可以新增命令、function、訊息顯示
ADD_COMMAND
是把 add_cmd()
再包裝一次,由於巨集展開後會把 cmd
和 do_cmd
的 function 相連,因此要連結的 function名稱應該以 do_開頭
在 qtest.c 加入 do_shuffle
函式,有做 arguments 和 null 的檢查
在 qtest.c 內實作 shuffle,這邊會檢查 head 是否為null或empty,接著每次從還沒被 shuffle 的節點中,選一個來移動到尾端
cmp argument 的格式
要套用到本專案的話,單獨把 list_sort.h
list_sort.c
抽出並放入專案目錄,並做以下修改
qtest.c
的 do_sort() ,讓執行 sort 時後面加入 linux
參數可切換為 linux 版本的 sortOBJS
加入 list_sort.o
my merge sort | linux sort | |
---|---|---|
30k samples | 0.003 | 0.001 |
300k samples | 0.044 | 0.023 |
3M samples | 0.619 | 0.350 |
篇幅過長,另外開筆記 link
linenoiseHistoryAdd
或 linenoiseHistoryLoad
有關,而這兩個 function 都在 linenoise.h 被定義。問題點的呼叫順序為 main -> linenoiseHistoryLoad -> linenoiseHistoryAdd -> linenoiseHistoryAdd -> strdup
在 linenoise.c 有宣告history
回到 qtest.c 觀察 main ,在呼叫 linenoiseHistoryLoad
後,似乎沒有做任何事來讓 history 被釋放,因此第二點的推論或許是正確的
從 linenoice.h 中看到以下宣告,猜測這跟釋放 history 或 line 有關
linenoiseAtExit
和 freeHistory
在專案有哪些地方會被執行,結果完全沒有,證實了第 2 點的猜想,根本沒有去釋放 history
linenoiseAtExit
或是 freeHistory
了linenoiseAtExit
從 static void 改成 void 來改變可視範圍,並移動宣告到 header filelinenoise.h
,因此嘗試加在finish_cmd()
內,會選擇加在這是因為: qtest.c 在 main 結束前有呼叫 finish_cmd()
來檢驗程式有沒有正確關閉