當我試圖從電影數據庫中刪除電影時,我收到segmentation fault
。我無法弄清楚爲什麼?分段錯誤刪除節點
我跑了GDB的程序,我在這裏得到一個分段錯誤:
(previousNode->next)->previous = previousNode;
任何建議,爲什麼我在這裏得到一個問題?
當我試圖從電影數據庫中刪除電影時,我收到segmentation fault
。我無法弄清楚爲什麼?分段錯誤刪除節點
我跑了GDB的程序,我在這裏得到一個分段錯誤:
(previousNode->next)->previous = previousNode;
任何建議,爲什麼我在這裏得到一個問題?
如果您嘗試刪除的節點是最後一個,該怎麼辦?然後currentNode->next
(因此previousNode->next
)將爲NULL
,並且您嘗試訪問NULL
指針導致未定義的行爲和可能的崩潰。
你可以通過簡單的檢查來解決這個問題,如果previousNode->next
是NULL
或者不需要解除引用。
很有可能你有一個空指針,但它也可能是一個糟糕的指針。
既然你正在運行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 */
}
(previousNode-> next) - > previous = previousNode; //分段故障
如果列表大小是兩個要刪除的第二個節點,那麼這將導致錯誤,因爲你previousNode->next
將是NULL,所以(previousNode->next)->previous
將成爲(NULL)->previous
這是錯誤。
這樣做:
if(previousNode->next!=NULL)
(previousNode->next)->previous = previousNode;
如果您刪除的是電影,我想,你從一個元素中刪除引用當前元素,然後,解引用(我們需要看到前面的源代碼行肯定)。這可以解釋爲什麼previousNode->next
是NULL
。解決此問題的最佳方法是在刪除之前通過解引用:
node* oldPrevious = NULL;
if(previousNode && previousNode->next)
{
oldPrevious = (previousNode->next)->previous;
(previousNode->next)->previous = previousNode;
}
if(oldPrevious)
free(oldPrevious);
使用'gdb'的Bravo。但是你應該更廣泛地使用它(例如使用它的'backtrace','display','print','watch'等...命令)。還可以使用[valgrind](http://valgrind.org/);或許'previousNode-> next'是'NULL' ...(使用'print'檢查'gdb') –
你確定要'free(title)'嗎?如果調用者傳入字符串或數組中的字符串,會怎麼樣?然後它沒有被'malloc'分配,並且不能被釋放。 –
這是正確的。它是NULL。我該如何解決它?有任何想法嗎 ? – user3020169