###### tags: `homework` `sysprog2017` 2017q3 Homework2(prefix-search) === contributed by <`Jetudie`> >您是不是沒有填寫課程表單? >[name=課程助教][color=red] >>當初錯填帳號名稱,已找老師修改 >>若有需要,可再重填一份表單給您 >>[name=Jetudie][color=royalblue] --- 題目: [C04: prefix-search](https://hackmd.io/s/Bki0g_P3Z) ### Reviewed by `jackyhobingo` * 實驗上發現會有 search 'A' 時會發生 segfault,解決了嗎?若沒有解決可以參考我的[解決方法](https://hackmd.io/s/B1V8tv33W) * 查看原始資料會發現輸入是 "city, country" or "city, city, country",會有逗號的都是城市,也許可以修改輸入時 split 的方法,將逗號處理掉 ## 編譯及測試 + 取得程式碼、編譯並執行 ``` $ git clonehttps//github.com/sysprog21/prefix-search $ cd prefix-search $ make $ ./test_cpy ``` + 出現如下 ``` ternary_tree, loaded 259112 words in 0.128302 sec Commands: a add word to the tree f find word in tree s search words matching prefix d delete word from the tree q quit, freeing all data choice: ``` ### 測試 find the word in tree + 輸入 `f` 按下 Enter, 輸入 `Taiwan`, 再按 Enter ``` find word on tree: Taiwan found Taiwan in 0.000002 sec. ``` + 輸入 `f` 按下 Enter, 輸入 `Tai`, 再按 Enter ``` find word on tree: Tai Tai not found. ``` ### 測試 search the words matching prefix + 接著又出現選擇畫面,輸入 `s` 按下 Enter, 再搜尋 `Tain` ``` find words matching prefix (at least 1 char): Tain Tain - seacjed prefix in 0.000013 sec suggest[0] : Tain, suggest[1] : Tainan, suggest[2] : Taino, suggest[3] : Tainter suggest[4] : Taintrux, ``` 發現==有些資料後面有逗號 (comma),有些則無== 接著看到 [jackyhobingo 的分析](https://hackmd.io/s/B1V8tv33W)之後,也試試以單一字母開頭搜尋 + 搜尋 `T` , 得到的結果為 1024 筆,末項是 `Tasqillo` 。發現其中==出現重複的資料==,差別只在後面有無 comma, 列出其中幾項示意 ``` ... suggest[57] : Tío suggest[58] : Tío, ... suggest[112] : Týn suggest[113] : Týn, ... suggest[274] : Tabor suggest[275] : Tabor, ... suggest[944] : Tarnów suggest[945] : Tarnów, ... suggest[1023] : Tasquillo, ``` 看末項,顯然 `Ta` 都沒列完,接著搜尋 `Tas` , 發現 `Tasquillo` 後面的確還有資料。又以`B`搜尋,得到同樣的結果,目前結論為此程式==最多一次列出 1024 筆資料== + 搜尋 `A` , 發現得到以下結果 ``` find words matching prefix (at least 1 char): A Segmentation fault (core dumped) ``` --- ## 探討在 find words matching prefix, 輸入 A 發生 Segmentation fault 的原因 + 用 gdb 找錯誤在哪發生 ``` $ gdb ./test_cpy ... (gdb) run ... choice: s find words matching prefix (at least 1 char): A Program received signal SIGSEGV, Segmentation fault. 0x0000555555555eea in tst_suggest (p=0x555556b1cb90, c=65 'A', nchr=1, a=0x7fffffffbdd0, n=0x7fffffffbd90, max=1024) at tst.c:330 330 a[(*n)++] = (char *) p->eqkid; ``` 發現在 tst.c:330 發生 Segmentation fault ```clike=317 void tst_suggest(const tst_node *p, const char c, const size_t nchr, char **a, int *n, const int max) { if (!p || *n == max) return; tst_suggest(p->lokid, c, nchr, a, n, max); if (p->key) tst_suggest(p->eqkid, c, nchr, a, n, max); else if (*(((char *) p->eqkid) + nchr - 1) == c) a[(*n)++] = (char *) p->eqkid; tst_suggest(p->hikid, c, nchr, a, n, max); } ```