我开始用C编写这个非常简单的函数,将node添加到头部的单个链接列表中。这是我的函数。参数head
是指向链表第一个节点的指针。如果链表为空,它可以是NULL
。data
为要添加的新节点的data字段中的数字:
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;
};
这在我的机器上有效,但在我同事的机器上无效。在另一台机器上,程序给出了分段错误。我的函数出了什么问题?
您的函数返回具有自动存储(又名堆栈) 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,您传递头指针的地址,只有在分配成功时才会更新。
您已经为新节点使用了一个局部变量,该变量将在函数退出时失效。当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;
}