从零开始的链表实现,分段错误

linked list implemetation from scratch, segmentation fault

我想从头开始实现链表。我对它进行了编程,但是当我 运行 它在我的 node_adder(int data) 函数中给我一个分段错误。我不知道是什么原因造成的。

struct linked_list
{
    int value;
    struct linked_list *next;
};

struct linked_list *head = NULL;
struct linked_list *tail = NULL;

void node_adder(int data)
{
    struct linked_list *new = NULL;

    new->value = data;
    new->next = NULL;

    if (head == NULL)
    {
        head = new;
        tail = new;
        printf("head added\n");
    }
    else
    {
        tail->next = new;
        tail = new;
        printf("tail added\n");
    }
}

此行将指向节点的指针初始化为 NULL:

struct linked_list *new = NULL;

然而,没有为这个节点分配内存。因此,在这一行中,尝试为节点的其中一个成员赋值会导致分段错误:

new->value = data;

您可能打算这样做:

struct linked_list *new = malloc(sizeof(struct linked_list));

当然,当分配的内存不再使用时,也应该添加相应的free(..)

node_adder() 中,您在访问其成员之前没有为新节点分配任何内存。

试试这个:

struct linked_list
{
    int value;
    struct linked_list *next;
};
    
struct linked_list *head = NULL;
struct linked_list *tail = NULL;

void node_adder(int data)
{
    struct linked_list *newNode;

    // ADD THIS!!!
    // in C:
    newNode = malloc(sizeof(struct linked_list));
    // in C++:
    newNode = new linked_list;
    //

    newNode->value = data;
    newNode->next = NULL;

    if (head == NULL)
    {
        head = tail = newNode;
        printf("head added\n");
    }
    else
    {
        tail->next = newNode;
        tail = newNode;
        printf("tail added\n");
    }
}

对于初学者来说,声明全局变量并定义依赖于全局变量的函数是一个坏主意

struct linked_list *head = NULL;
struct linked_list *tail = NULL;

因为在这种情况下您将无法定义多个列表。

再引入一种结构就好了,比如

struct node
{
    int value;
    struct node *next;
};

struct linked_list
{
    struct node *head;
    struct node *tail;
};

至于你的问题,那么你正在使用空指针访问导致未定义行为的内存

void node_adder(int data)
{
    struct linked_list *new = NULL;

    new->value = data;
    new->next = NULL;
    //...

您需要动态分配一个节点,例如

int node_adder(int data)
{
    struct linked_list *new = malloc( sizeof( *new ) );
    int success = new != NULL;

    if ( success )
    {
        new->value = data;
        new->next = NULL;

        if (head == NULL)
        {
            head = new;
        }
        else
        {
            tail->next = new;
        }

        tail = new;
    }

    return success;
}

但是使用我在回答开头展示的方法你可以改写

struct node
{
    int value;
    struct node *next;
};

struct linked_list
{
    struct node *head;
    struct node *tail;
};

int node_adder( struct linked_list *list, int data )
{
    struct node *new = malloc( sizeof( *new ) );
    int success = new != NULL;

    if ( success )
    {
        new->value = data;
        new->next = NULL;

        if (list->head == NULL)
        {
            list->head = new;
        }
        else
        {
            list->tail->next = new;
        }

        list->tail = new;
    }

    return success;
}

主要你可以写

int main( void )
{
    struct linked_list list = { .head = NULL, .tail = NULL };

    node_adder( &list, 10 );
    //...
}