# 2023q1 Homework1 (lab0) contributed by <[`Otuslettia`](https://github.com/Otuslettia)> ## 開發環境 ``` $ gcc --version gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 ``` > 此處參考[hongpei100](https://hackmd.io/@MrShark/S1Z73ZTTj#%E5%AF%A6%E9%A9%97%E7%92%B0%E5%A2%83)的文章中,老師關於 `lscpu` 套件的回覆,先執行 `$export LC_ALL=C` ``` $export LC_ALL=C $lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Address sizes: 39 bits physical, 48 bits virtual Byte Order: Little Endian CPU(s): 12 On-line CPU(s) list: 0-11 Vendor ID: GenuineIntel Model name: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz CPU family: 6 Model: 165 Thread(s) per core: 2 Core(s) per socket: 6 Socket(s): 1 Stepping: 2 CPU max MHz: 5000.0000 CPU min MHz: 800.0000 BogoMIPS: 5199.98 ``` ## 開發過程 ### queue.c #### `q_new()` 首先用 `malloc` 配置記憶體,當 allocation fail 時回傳 `NULL`,通過 `INIT_LIST_HEAD()` 將 `list->next` 及 `list->head` 指回 `list`。 ``` struct list_head *q_new() { struct list_head *new = malloc(sizeof(struct list_head)); if (!new) return NULL; INIT_LIST_HEAD(new); return new; } ``` #### `q_free()` 用`list_for_each_entry_safe` 走訪每一個元素,然後依序釋放記憶體。 ``` /* Free all storage used by queue */ void q_free(struct list_head *l) { element_t *entry, *safe; list_for_each_entry_safe (entry, safe, l, list) { q_release_element(entry); } free(l); } ``` #### `q_insert_head()` / `q_insert_tail` `q_insert_head()` 及 `q_insert_tail()` 有重複 `malloc` `element_t` 行為 [e2e4af4](e2e4af4127db09baa668c9f7615608051c949018)。 `[!] You are not allowed to change the header file queue.h or list.h` ,將重複部份寫成函式放在 `queue.c` 裡面。 * 若 `strdup()` `malloc fail`,要記得釋放已配置的記憶體,否則有 `memory leak` 問題。 * 避免 `element_new_char()` 回傳指標和 `head` 一起判斷,否則 `head` 為 `NULL` 時,須對新建 `element_t` 執行 `free()` 。 ``` element_t *element_new_char(char *s) { if (!s) return NULL; element_t *s_new = malloc(sizeof(struct list_head)); if (!s_new) return NULL; s_new->value = strdup(s); if (!s_new->value) { free(s_new); return NULL; } return s_new; } ``` #### `q_remove_head()` 當 `sp` 為 `NULL` 時,應直接 `remove` ,不複製 `value` 進 `sp` ,起初誤以為 `sp` / `head` 其一為 `NULL` 時就回傳 `NULL` [364819c](364819c718c2875ba4c9bca6cb76fa019a5f49aa)。 * `list_del()` 會處理 `list_head` 內容的指標更改,不會進行 `free()` 。 ``` /* Remove an element from head of queue */ element_t *q_remove_head(struct list_head *head, char *sp, size_t bufsize) { if (!list_empty(head)) return NULL; element_t *toRem = list_first_entry(head, element_t, list); if (sp) { memset(sp, '\0', bufsize); strncpy(sp, toRem->value, bufsize - 1); } list_del(&toRem->list); return toRem; } ```