contributed by < YiChiChao >
yu-hsiennn
多利用 graphviz
來製圖
過去整理筆記很習慣中英夾雜,透過這學期的學習希望能改變這樣的行為。
remove_list_node
為例):
list->head
和 prev->next
都需要更新。&list->head
,以「要更新的位址」為思考點來操作,而後指標的指標皆為指向 &node->next
。刪除的操作,實質上是去更新特定指標的位址中的內容,而不是單就個別的node 去判別。使用作業規範的程式碼縮排風格。
q_new
透過 malloc
配置記憶體,並且透過 list.h
中的 INIT_LIST_HEAD
初始結構體。
無論標題和內文中,中文和英文字元之間要有空白字元 (對排版和文字搜尋有利)
list.h
中有 LIST_HEAD(head)
和 INIT_LIST_HEAD(struct list_head *head)
兩個功能很類似的函式/巨集。LIST_HEAD
是直接宣告一個區域變數並且完成初始化的巨集,INIT_LIST_HEAD
只負責初始化傳入的 list_head
指標。
allocate 翻譯為「配置」,以區隔 dispatch (分發/分配) 的翻譯,二者在作業系統領域都是常見詞彙。
了解,已修正。YiChi Chao
之所以不能直接用 LIST_HEAD(head)
而要動態配置記憶體,再用 INIT_LIST_HEAD
初始化指標,是因為在函式中宣告的區域變數會被配置到 stack 中,當函式返回時會自動將此區域回收,此時即使回傳此結構體的指標,指標的內容也可能為未定義之內容。透過 malloc
配置的記憶體在 heap 中,此區的記憶體需要透過 free
來釋放。所以 malloc
配置的記憶體的結構體指標回傳後,其內容並不會因為函式結束而被回收。
q_free
q_insert_head
string 是「字串」。
strdup
是用來動態複製一個以 '\0'
結尾的字串,並回傳字串指標。
strdup(3) — Linux manual page,"The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3)."
Delete 的時候在處理記憶體問題時,除了結構體本身,要記得處理字串本身記憶體的回收。
在 commit 時遇到 error
最後的解決方式是將 &(nownode->next)
改成 &nownode->next
。
q_insert_tail
從 terry23304 看到可重用 q_insert_head
的建議,將插入 Head
的尾看作插入 Head->prev
的頭。
HackMD 不是讓你張貼完整程式碼的地方,GitHub 才是!因此你在開發紀錄只該列出關鍵程式碼 (善用 diff 標示),可附上對應 GitHub commit 的超連結,列出程式碼是為了「檢討」和「便於他人參與討論」,不是用來「假裝自己有付出」
了解,先刪除此部份
container_of
由已知結構體中的 某個成員起始位址 去獲得此成員所在之 結構體的起始位址。
利用成員起始位址ptr
扣掉成員在結構體中相對位址。
避免非必要的項目列表 (即 *
),以清晰且明確的漢語書寫。
q_delete_dup
此函式的目的是要消除佇列中重複的字串節點。在條件判斷會有三種情況:
前兩者皆為字串重複,第二種除了消除目前節點外,還需要更新紀錄重複字串之變數( prob
)
原本更新 prob
的寫法為直接透過 strdup
重新動態配置字串空間,紀錄最新重複字串。
當透過 make check
搭配 trace-06-ops.cmd
測試時,會發現有兩個配置的位置沒有被釋放
更仔細地印出目前釋放位置的字串內容才發覺,當透過 strdup
來更新 prob
的字串時,未釋放前一個 prob
字串的位置。
在更新 prob
前,先釋放目前字串之位置,將 prob
設為 NULL ,再進行更新。
改為以下:
注意看 free(3)。