将头节点添加到单个链接列表会导致分段错误错误

时间:2016-10-29 13:42:10

标签: c data-structures linked-list

我开始在C中编写这个非常简单的函数,将节点添加到头部的单个链接列表中。这是我的功能。 head参数是指向链表的第一个节点的指针。如果链表为空,它可以为NULLdata是要添加到新节点的数据字段中的数字:

Node* InsertAtHead(Node *head, int data)
{
    Node newHeadNode;
    newHeadNode.data = data;
    newHeadNode.next = NULL;

    if (head == NULL)
    {
        head = &newHeadNode;
    }
    else
    {
        newHeadNode.next = head;
        head = &newHeadNode;
    }

    return head;
}

Head的定义如下:

struct Node
{
    int data;
    struct Node *next;
};

这适用于我的机器,但不适用于我同事的机器。在另一台机器上,程序给出了分段错误错误。我的功能出了什么问题?

2 个答案:

答案 0 :(得分:1)

您的函数返回具有自动存储(也称为堆栈newHeadNode的局部变量的地址。在程序的其余部分中使用它会调用未定义的行为。您应该使用malloc()分配节点,并将指针返回到已分配的对象:

#include <stdlib.h>

Node *InsertAtHead(Node *head, int data) {
    Node *node = malloc(sizeof(*node));
    if (node != NULL) {
        node->data = data;
        node->next = head;
    }
    return node;
}

请记住将返回值存储到列表的堆指针中,除非它为NULL。另一种更安全的API是:

Node *InsertAtHead(Node **head, int data) {
    Node *node = malloc(sizeof(*node));
    if (node != NULL) {
        node->data = data;
        node->next = *head;
        *head = node;  // update the head pointer
    }
    return node;
}

使用此API,您可以传递头指针的地址,只有在分配成功时才会更新。

答案 1 :(得分:0)

您已为新节点使用了局部变量,该变量在函数退出时将变为无效。在head == NULL时,也无需单独创建条件。

Node* InsertAtHead(Node *head, int data)
{
    Node *newNode = malloc(sizeof *newNode);   // note: check the pointer
    newNode->data = data;
    newNode->next = head;
    return newNode;
}