contributed by < Korin777
>
malloc
一個 head
並回傳 , 後來發現這樣就無法透過 list.h
所提供的 list_empty
來判斷 list 是否為空 , 且這樣的 linked list 也並不是雙向環狀的list.h
提供的 INIT_LIST_HEAD
將 head
的 prev
及 next
都指向自己 , 完成雙向環狀的 linked listlist.h
提供的 list_for_each_entry_safe
遍歷 list 並釋放每個 entry
所配置過的記憶體空間entry
皆為 element_t
entry
要先釋放 element_t ->value
在釋放 element_t
head
, 因為它並不是 list
中的一個 entry
而是用來當作 list 的開頭malloc
一個 element_t
作為 list 中一個 entry
element_t->value
的 size 為 strlen(s)+1
, 最後一個字元用來存放空字元 \0
element_t->list
是 struct list_head
的型態 , 為實際 linked list 互相連接的節點 , 透過 list.h
提供的 list_add
來將它加在 linked list 的最前面(不包含head
)element_t ->value
記憶體失敗時 , 要釋放element_t
的記憶體 , 才不會產生 memory leaklen
變數來儲存 s
的長度 , 減少重複呼叫 strlen
所花的時間 , 不過在測試 time complexity 有時還是會沒通過q_insert_head
差再需用 list.h
提供的list_add_tail
來連接節點list.h
所提供的 list_entry
, 有了包含在 element_t
中的 list
記憶體位置 , 就能算出此 element_t
的記憶體位置element_t->value
複製到 sp
並將最後一個字元設為空字元 \0
list.h
所提供的 list_del
, 將節點移除q_remove_head
差在移除的節點為 head->prev
list.h
提供的 list_for_each
遍歷 linked list 來取長度h
一開始為第一個節點 , t
一開始為最後一個節點h
一直往後走 , t
則一直往前走 , 當兩者相同或 h->next
與 t
相同時 , h
恰好為中點tmp
為字元指標 , 配置記憶體前 tmp
不為 NULL 要先釋放 tmp
的記憶體 , 以免產生 memory leaktmp
為 NULL 或 tmp
和當前 entry
的字串不同 , 就看下個 entry
的字串是否與當前字串一樣 , 來判斷是否該移除當前節點及釋放對應的記憶體tmp
和當前 entry
的字串相同 , 直接移除當前節點及釋放對應的記憶體tmp
最後不為 NULL 要釋放 tmp
記憶體li
為相鄰 node 的第一個 node , tmp
則為第二個 node , 並將兩者互換li
為 head
或 tmp
為 head
, 表示已經沒有相鄰的 node 需要互換h
一開始為第一個節點 , t
一開始為最後一個節點h
一直往後走 , t
則一直往前走 , 因為 h
跟 t
互換 , h
要更新為 t->next
, t
則更新為 h->next
h
與 t
相同或 t->next->prev
與 t
相同 , linked list 已反轉完畢trace-17-complexity
有時會沒 pass 的原因只跟 q_insert_tail, q_insert_head, q_remove_tail, q_remove_head 有關 , 後來發現原來是我 q_reverse 寫錯了 , t->prev
是 t->next
才對 , 而 tmp
的宣告也是多餘的reverse
還是能成功將 reverse 後的 linke list show 出來 , 儘管前半段 linked list 節點的 prev
應該都是錯的trace-17-complexity
還是沒過 , 在本地端測試確實有時不會過 , 還要在看看是那出了問題qtest
跑 trace-14-perf.cmd
的測資 , 發現會 Segmetation Faultnext
改為 null , 在 split
時才不會又跑回最前面head
的 prev
、 最後一個節點的 next
及第一個節點的 prev
mergeTwoLists
, 透過指標的指標實做 merge
函式 , 簡化程式碼prev
指標並不會被修改 , 必須在 mergeSort
後把它改回來queue.c
中entry
的字串大小的 compare 函式沿用 trace-14-perf.cmd
的測資 , 並透過 qtest
所提供的 time
命令來測量排序時間
排序函式 | 執行時間 |
---|---|
My MergeSort | 0.95s |
Linux MergeSort | 0.55s |
console_init
新增 shuffle 指令ADD_COMMAND
是定義在 console.h
的巨集 #define ADD_COMMAND(cmd, msg) add_cmd(#cmd, do_##cmd, msg)
, 也是為什麼當我們想新增一個指令 cmd
, 對應的 function 一定要是 do_cmd
shuffle_point
為當前要調換位置的節點 , next_shuffle_point
為下一個要調換的節點prev
之後next_shuffle_point
在互換節點相鄰時 , 節點互換後這時shuffle_point
即為下次的 shuffle_point
, 所以 next_shuffle_point
要改為 shuffle_point->prev
透過 make valgrind 可以看到以下訊息 , 這裡取 trace-01-ops
產生的訊息來看 , 看起來像是有記憶體沒有釋放
qtest.c
linenoise.c
linenoiseHistoryAdd
的 linecopy
沒有釋放 , 因為他透過 strdup
配置記憶體卻沒釋放 , 便嘗試在函式結束前將它釋放 , 結果訊息卻便多了linenoiseHistoryLoad(HISTORY_FILE)
的 HISTORY_FILE
是什麼 , 發現原來是紀錄 qtest cmd
曾打過的指令紀錄 .cmd_history
, 而這些紀錄會記在 **history
這個類似字串陣列裡頭histroy
給釋放 , 寫了一個freeHistory 的函式來完成 , 卻發現 linenoise.c
原本就有定義這個函式了linenoise.c
裡寫一個函式 freelinenoise
來呼叫釋放 histroy 記憶體的函式 linenoiseAtExit
, 並在 qtest
主程式結束前呼叫它 , 成功解決 memory leak 的問題