尝试将节点添加到链表前面时出现段错误

Segfault when trying to add a node to front of linked list

我很困惑为什么我会在这段代码中遇到段错误。 gdb 说当我尝试将数据分配给列表-> 值时会发生段错误,但我无法弄清楚为什么会这样。感谢您的帮助!

 int main(){

    SingleLinkedListNode *list =  0;
    int element = 10;
    pushFront(list, element);
    //cout << list->value << endl;
}
    
SingleLinkedListNode *head = NULL;


void pushFront(SingleLinkedListNode*& list, const int data){
//checks if head points to null. if it does, 
//make head point to list and the data assigns to list->value
    if(list == NULL){
        head = list;
        list->value = data; //gdb says segfault occurs here
        return;

    }
// if head != null then make list point to the node head points to, assign 
// value to list->value and last make the head point to list node
    list->next = head;
    head = list;
    list->value = data;
    
}

我认为这是出于某种学术目的,因为实际上,当您可以只使用 std::forward_list 并完成它时,没有任何头脑正常的人会重新发明一个链表(不要重新发明轮子)。

您似乎对尝试将全局 head 指针绑定到 (a) 不需要它和 (b) 不需要它的解决方案感到困惑。更糟糕的是,您似乎不明白链表数据结构是 节点 的链,而且这些节点并非凭空而来。

你的错误来自这里:

if(list == NULL){ // test that list is NULL
    head = list;
    list->value = data; // list is NULL, so this dereference is bad.
    return;

有几处错误,最麻烦的是试图在 none 应该存在的地方修饰一个全局 head 指针。此外,在链表上挂一个新节点需要.... 一个新节点(我知道;这是一个疯狂的世界)。

假设您的结构如下所示:

struct SingleLinkedListNode
{
    int data;
    SingleLinkedListNode *next;

    SingleLinkedListNode(int arg=0, SingleLinkedListNode *nxt = nullptr)
        : data(arg)
        , next(nxt)
    {
    }

    // squelch these
    SingleLinkedListNode(const SingleLinkedListNode&) = delete;
    SingleLinkedListNode& operator =(const SingleLinkedListNode&) = delete;
};

将项目推到passed-in列表前面的方法很简单:

void pushFront(SingleLinkedListNode*& lst, int data)
{
    lst = new SingleLinkedListNode(data, lst);
}

请注意,这会执行以下操作:

  • 将新节点的数据值作为第一个参数传递给 SingleLinkedListNode 构造函数。
  • 将现有列表头指针值作为第二个参数传递给 SingleLinkedListNode 构造函数。这将用作正在构建的新节点的 next 成员值,从而将新节点链接到当前列表头。
  • 最后,将结果 pointer-to-node 存储为新的链表头,它将传播回调用者,因为 lst 是对 caller-provided 的 non-const 引用指针。

这也意味着您不需要(也不应该想要)全局 head。下面提供了此解决方案的完整示例。

#include <iostream>

struct SingleLinkedListNode
{
    int data;
    SingleLinkedListNode *next;

    SingleLinkedListNode(int arg=0, SingleLinkedListNode *nxt = nullptr)
        : data(arg)
        , next(nxt)
    {
    }

    // squelch these (Rule of 3/5/0 habit)
    SingleLinkedListNode(const SingleLinkedListNode&) = delete;
    SingleLinkedListNode& operator =(const SingleLinkedListNode&) = delete;
};

void pushFront(SingleLinkedListNode*& lst, int data)
{
    lst = new SingleLinkedListNode(data, lst);
}

void printList(const SingleLinkedListNode *lst)
{
    if (lst)
    {
        std::cout << lst->data;
        lst = lst->next;
        while (lst)
        {
            std::cout << ',' << lst->data;
            lst = lst->next;
        }
        std::cout << '\n';
    }
}

void freeList(SingleLinkedListNode*& lst)
{
    while (lst)
    {
        SingleLinkedListNode *tmp = lst;
        lst = lst->next;
        delete tmp;
    }
}

int main()
{
    SingleLinkedListNode *head = nullptr;

    for (int i=1; i<=10; ++i)
        pushFront(head, i);

    printList(head);
    freeList(head);
}

输出

10,9,8,7,6,5,4,3,2,1