簡體   English   中英

分段故障從單鏈列表中刪除節點

[英]Segmentation fault deleting nodes from singly linked list

這是我正在研究的情況

[11] -> [12] -> [13] -> NULL

我試圖從上面的喜歡的列表中刪除元素(示例),但是我一直在遇到段錯誤,並且在運行GDB時並沒有太大幫助。 我不是在尋找答案,而是在邏輯上哪里出了問題。

這是代碼

int
List:: remove( int val )
{
    ListNode *headNode = _head;
    ListNode *tempNode = NULL;

    if(headNode->_value == val){
        tempNode = headNode->_next;
        delete headNode;
        _head = tempNode;
    }
    else
    {
        while(headNode->_value != val){
            tempNode = headNode;
            headNode = headNode->_next;
        }
        tempNode->_next = headNode->_next;
        delete headNode;

    }
}

您沒有考慮以下情況:

  • 該列表可能為空; _headNULL ;
  • 該值可能根本不在列表中。
  • 您的函數聲明為返回int ,但不進行此類return

假設您其余的代碼是正確的(這是一個很大的假設),我可以肯定地說,這就是您要嘗試執行的操作:

void List::remove( int val )
{
    ListNode *headNode = _head;
    ListNode *tempNode = NULL;

    while (headNode && headNode->_value != val)
    {
        tempNode = headNode;
        headNode = headNode->next;
    }

    if (headNode)
    {
        if (tempNode)
            tempNode->next = headNode->next;
        else
            _head = headNode->next;

        delete headNode;
    }
}

另外,如果傾斜的話,使用指針到指針遍歷列表中的指針 (而不只是指針的值)會變得更簡單。 值得研究以下內容的工作方式,這些內容仍然涵蓋了前面描述的所有基礎,但是使用列表節點本身中的實際指針(包括_head ,by-address而不是by-value)來進行此工作,從而消除了漫游的需要-在臨時指針后面:

void List::remove( int val )
{
    ListNode **pp = &_head;

    while (*pp && (*pp)->_value != val)
        pp = &(*pp)->next;

    if (*pp)
    {
        ListNode *p = *pp;
        *pp = p->next;
        delete p;
    }
}
  1. 在您的remove方法中,您假設列表中始終有元素。 -如果是空的怎么辦?

  2. 如果該值不在列表中怎么辦? 您還需要處理這種情況。


您正朝着正確的方向前進-僅有少數未考慮到的情況可能會導致您出現段錯誤。

帶刪除的正向遍歷示例(僅向前鏈接列表):

// Start from the beginning (head), then while the current isn't null, 
// move to the next node.
for (ListNode* current = head; current != null; current = current->next) {

    // Check the next item if there is one, and remove it if it matches the value.
    // We check the next one because you can't delete the current node in a 
    // forward only linked list (can in a doubly-linked list however)
    if (current->_next != nullptr && current->_value == value) {

        // Make this item point to the next next item 
        // (Since we're gonna delete the next item)
        current->_next = current->_next->next;

        // Delete the next item.
        delete current->_next;
     }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM