2013-11-22 92 views
0

當我試圖從電影數據庫中刪除電影時,我收到segmentation fault。我無法弄清楚爲什麼?分段錯誤刪除節點

我跑了GDB的程序,我在這裏得到一個分段錯誤:

(previousNode->next)->previous = previousNode; 

任何建議,爲什麼我在這裏得到一個問題?

+3

使用'gdb'的Bravo。但是你應該更廣泛地使用它(例如使用它的'backtrace','display','print','watch'等...命令)。還可以使用[valgrind](http://valgrind.org/);或許'previousNode-> next'是'NULL' ...(使用'print'檢查'gdb') –

+0

你確定要'free(title)'嗎?如果調用者傳入字符串或數組中的字符串,會怎麼樣?然後它沒有被'malloc'分配,並且不能被釋放。 –

+0

這是正確的。它是NULL。我該如何解決它?有任何想法嗎 ? – user3020169

回答

1

如果您嘗試刪除的節點是最後一個,該怎麼辦?然後currentNode->next(因此previousNode->next)將爲NULL,並且您嘗試訪問NULL指針導致未定義的行爲和可能的崩潰。

你可以通過簡單的檢查來解決這個問題,如果previousNode->nextNULL或者不需要解除引用。

1

很有可能你有一個空指針,但它也可能是一個糟糕的指針。

既然你正在運行gdb,你可以打印東西。打印一些東西,看看你能弄清楚什麼。

從GDB提示:

p previousNode 

previousNode一個空指針?如果不是:

p previousNode->next 

現在怎麼樣,是一個空指針?

無論何時將->運算符應用於空指針,您都會遇到seg故障錯誤。

另一件嘗試:在分配節點的函數中設置一個斷點,並嘗試打印節點地址。例如,我剛寫了一個簡單的C程序,名爲malloc(),結果地址是0x17b0010。如果我打印一個像previousNode這樣的變量,並且它與0x17b01000類似,那麼看起來似乎是合理的;如果它是類似0xdcdcdcdc這不合理的。無論這個地址是什麼,它可能不是我的程序(更可能它根本不是一個有效的指針)。

而我第二次推薦Valgrind。它可以找到您可能使用malloc()free()所犯的各種細微錯誤。

一個更多的想法:你可以添加一個成員到你的節點結構,一個只用於「理智檢查」的成員。我經常添加一個名爲sig(簡稱「簽名」)的成員,並且在我的每個結構中包含不同的值。然後,與結構一起工作的代碼可以檢查sig值,如果設置不正確,則必定會出現某種錯誤。例如:

if (!previousNode || !previousNode->next || previousNode->sig != NODE_SIG_VALUE) 
{ 
    return ERROR_CODE_BAD_NODE; 
} 
else 
{ 
    (previousNode->next)->previous = previousNode; 
    return 0; /* SUCCESS */ 
} 
2

(previousNode-> next) - > previous = previousNode; //分段故障

如果列表大小是兩個要刪除的第二個節點,那麼這將導致錯誤,因爲你previousNode->next將是NULL,所以(previousNode->next)->previous將成爲(NULL)->previous這是錯誤。

這樣做:

if(previousNode->next!=NULL) 
    (previousNode->next)->previous = previousNode; 
0

如果您刪除的是電影,我想,你從一個元素中刪除引用當前元素,然後,解引用(我們需要看到前面的源代碼行肯定)。這可以解釋爲什麼previousNode->nextNULL。解決此問題的最佳方法是在刪除之前通過解引用:

node* oldPrevious = NULL; 

if(previousNode && previousNode->next) 
{ 
    oldPrevious = (previousNode->next)->previous; 
    (previousNode->next)->previous = previousNode; 
} 

if(oldPrevious) 
    free(oldPrevious);