2012-01-12 113 views
3

編輯:Dijkstra的答案是解決這個問題的方法。我的列表未初始化爲NULL鏈接列表中的分段錯誤

我正在處理鏈接列表以存儲單詞的唯一列表,當我嘗試遍歷列表時發生段錯誤。 GDB給我:

Program received signal SIGSEGV, 
    Segmentation fault. 0x0000003a07e47ff7 in vfprintf() from /lib64/libc.so.6 
    Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.7.el6_0.5.x86_64 

對列表中的插入代碼:

typedef struct L { char x[40] ; int occ; struct L *next ;} List; 
List *insertList(char *in, List *l) 
{ 
    List *t = calloc(1, sizeof(List)) ; 
    strcpy(t->x, in); 
    t->occ = 1; 
    t->next = l ; 
    return t ; 
} 

void printList(List *l) 
{ 
    List *l2 = l; 
    while(l2) 
    { 
     printf("%s ", l2->x); 
     l2 = l2->next; 
    } 
    return; 
} 

它通過循環的話,將它們插入到鏈表中,似乎罰款。當我循環顯示單詞(大約4200字)時,大約98%的ish會顯示正常,然後它會在沒有警告的情況下進行段錯誤。

隨着一些更多的檢查,它會按照與添加它們相反的順序(這是有道理的)讀回單詞,並且會在截斷之前從列表末尾(添加的第5個單詞)到第5個單詞。我已經嘗試調整插入函數以允許長度超過40個字符的字符串,但是在開頭插入的單詞(以及被隔離)都不到20個字符。

隨着更多的挖掘,如果我在printList函數中printf l2-> next-> next-> next-> next,插入的第一個單詞就在那裏。

任何人都可能指出我在這個正確的方向嗎?

感謝

+0

打印清單的代碼請好嗎? – nmjohn 2012-01-12 22:27:08

+0

首先,養成使用'strncpy'而不是'strcpy'的習慣。 – thiton 2012-01-12 22:28:33

+0

是否超過39個字的單詞之一?你應該使用'strncpy'來確保你不會超出內存。 – ugoren 2012-01-12 22:29:19

回答

2

我最好的猜測是,函數strncpy代替strcpy的將解決您的問題,聽起來有點像已覆蓋你的「下一個」指針列表中後期的某個地方,並在「在」過長的字符串肯定會這樣做。

不要忘記,strncpy()函數將不會終止過長的字符串,所以要確保把

x[39]=0; 

,以確保該字符串將被正確終止。

+0

謝謝,我嘗試了你的建議,但無濟於事。稍微挖掘一下,我發現由於某種原因,插入的前幾個單詞導致了seg故障。如果我刪除前幾個單詞,那麼接下來的幾個單詞(在前面的例子中很好)現在是問題 – ethangk 2012-01-12 23:05:45

+0

那麼也許你的代碼中的其他地方有內存覆蓋。 – 2012-01-13 00:54:25

3

gdb(或另一個調試器,如果您不使用Linux)是我的跟蹤段錯誤的首選工具。用調試符號編譯代碼並在調試器中運行它。當你崩潰時,檢查導致崩潰的線路。根據需要使用backtrace命令。遵循這些步驟幾乎總是告訴我如何修復段錯誤。

2

你如何初始化你的第一個節點?

你說「前幾個單詞導致seg故障」,但中斷可能會阻止他們打印,問題實際上是在最後結束。

我的假設(這實際上只是一個猜測:P)是您的第一個節點沒有next = NULL;,它只是未初始化的內存。因此,while循環沒有檢測到它到達列表的末尾,並嘗試打印奇怪的東西,導致段錯誤。

+0

我們有一個贏家。我設法讓它在一兩個小時前工作,但這是問題所在。我不小心將另一個列表初始化爲NULL。謝謝:) – ethangk 2012-01-13 00:50:15

2

這是一個文體上的評論(這不會被SO人們所讚賞; - [) 平原for循環有什麼問題?爲什麼你在循環內迭代,當這種事情有一個有效的慣用構造?

void printList(List *lp) 
{ 
    List *l2; 

    for(l2=lp; l2; l2 = l2->next) 
    { 
     printf("%s ", l2->x); 
    } 
    return; 
} 
+0

老實說,我沒有想過這樣做,但它似乎更清潔。最初的問題已經解決,但我真的很喜歡這個。謝謝 – ethangk 2012-01-13 01:25:23