分段故障从单链表中删除节点

时间:2014-06-19 20:17:36

标签: c

这是我正在处理的案例

[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;

    }
}

3 个答案:

答案 0 :(得分:3)

您未考虑以下条件:

  • 列表可能为空;即_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,按地址而不是按值,这样就消除了需要一个手扶式临时指针:

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 :(得分:0)

  1. 在您的删除方法中,您假设列表中始终有元素。 - 如果它是空的怎么办?

  2. 如果值不在列表中怎么办?你也需要处理这个案例。


  3. 你正朝着正确的方向前进 - 只有少数你没有考虑过会导致你出错的情况。

答案 2 :(得分:0)

带删除的正向遍历示例(仅向前链接列表):

// 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;
     }

}