or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Do you want to remove this version name and description?
Syncing
xxxxxxxxxx
2022q1 Homework1 (lab0)
contributed by <
Korin777
>開發環境
queue.c 實作
q_new
malloc
一個head
並回傳 , 後來發現這樣就無法透過list.h
所提供的list_empty
來判斷 list 是否為空 , 且這樣的 linked list 也並不是雙向環狀的list.h
提供的INIT_LIST_HEAD
將head
的prev
及next
都指向自己 , 完成雙向環狀的 linked listq_free
list.h
提供的list_for_each_entry_safe
遍歷 list 並釋放每個entry
所配置過的記憶體空間entry
皆為element_t
entry
要先釋放element_t ->value
在釋放element_t
head
, 因為它並不是list
中的一個entry
而是用來當作 list 的開頭q_insert_head
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_tail
q_insert_head
差再需用list.h
提供的list_add_tail
來連接節點q_remove_head
list.h
所提供的list_entry
, 有了包含在element_t
中的list
記憶體位置 , 就能算出此element_t
的記憶體位置element_t->value
複製到sp
並將最後一個字元設為空字元\0
list.h
所提供的list_del
, 將節點移除q_remove_tail
q_remove_head
差在移除的節點為head->prev
q_size
list.h
提供的list_for_each
遍歷 linked list 來取長度q_delete_mid
h
一開始為第一個節點 ,t
一開始為最後一個節點h
一直往後走 ,t
則一直往前走 , 當兩者相同或h->next
與t
相同時 ,h
恰好為中點q_delete_dup
tmp
為字元指標 , 配置記憶體前tmp
不為 NULL 要先釋放tmp
的記憶體 , 以免產生 memory leaktmp
為 NULL 或tmp
和當前entry
的字串不同 , 就看下個entry
的字串是否與當前字串一樣 , 來判斷是否該移除當前節點及釋放對應的記憶體tmp
和當前entry
的字串相同 , 直接移除當前節點及釋放對應的記憶體tmp
最後不為 NULL 要釋放tmp
記憶體q_swap
li
為相鄰 node 的第一個 node ,tmp
則為第二個 node , 並將兩者互換li
為head
或tmp
為head
, 表示已經沒有相鄰的 node 需要互換q_reverse
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
還是沒過 , 在本地端測試確實有時不會過 , 還要在看看是那出了問題q_sort
qtest
跑trace-14-perf.cmd
的測資 , 發現會 Segmetation Faultnext
改為 null , 在split
時才不會又跑回最前面head
的prev
、 最後一個節點的next
及第一個節點的prev
mergeTwoLists
, 透過指標的指標實做merge
函式 , 簡化程式碼prev
指標並不會被修改 , 必須在mergeSort
後把它改回來Linux list_sort
引入 lib/list_sort.c 到 lab0-c
queue.c
中entry
的字串大小的 compare 函式比較自己實做的 Merge Sort 和 Linux 核心程式碼之間效能落差
沿用
trace-14-perf.cmd
的測資 , 並透過qtest
所提供的time
命令來測量排序時間在 qtest 提供新的命令 shuffle
在 qtest.c 加上 shuffle 指令
console_init
新增 shuffle 指令ADD_COMMAND
是定義在console.h
的巨集#define ADD_COMMAND(cmd, msg) add_cmd(#cmd, do_##cmd, msg)
, 也是為什麼當我們想新增一個指令cmd
, 對應的 function 一定要是do_cmd
實做 Fisher–Yates shuffle
shuffle_point
為當前要調換位置的節點 ,next_shuffle_point
為下一個要調換的節點prev
之後next_shuffle_point
在互換節點相鄰時 , 節點互換後這時shuffle_point
即為下次的shuffle_point
, 所以next_shuffle_point
要改為shuffle_point->prev
運用 Valgrind 排除 qtest 實作的記憶體錯誤
透過 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 的問題