c - 为什么这个销毁函数在单链表中抛出段错误

标签 c pointers data-structures segmentation-fault

我是数据结构和 C 的新手。这段代码在创建和插入节点时可以正常工作,但是当我调用 destroy 函数时,它的情况是段错误。如果我将所有内容都放在其中,它似乎可以正常工作main函数中的代码而不是其他函数中的代码。

此错误是什么情况:

销毁

删除 IF仅删除链表的头部

谁能向我解释一下这有什么问题吗?

#include <stdio.h>
#include <stdlib.h>

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

node *create_node(int value);
unsigned char insert(node *head, int value);
unsigned char delete_node(node *head, node *old_node);
node *search(node *head, int value);
unsigned char destroy(node *head);

int main(void)
{
    node *head = create_node(1);
    insert(head, 3);
    insert(head, 2);

    destroy(head);

    for(node *i = head; i != NULL; i = i -> next)
    {
        printf("%i\n", i -> value);
    }
}

// Will create a node and return it if succeeded else it will return NULL
node *create_node(int value)
{
    node *new_node = malloc(sizeof(node));

    // Check if the node created successfully or not
    if (new_node == NULL)
    {
        return NULL;
    }

    new_node -> value = value;
    new_node -> next = NULL;

    return new_node;
}

// Insert the node to a list at the beginning of it, return 0 if succeed else number NOT 0
unsigned char insert(node *head, int value)
{
    node *new_node = create_node(value);

    // Check if the node created successfully or not
    if (new_node == NULL)
    {
        return 1;
    }

    // Check if the List is exist or not
    if (head == NULL)
    {
        return 2;
    }

    new_node -> next = head -> next;
    head -> next = new_node;

    return 0;
}

// Delete the node, return 0 if succeeded else number NOT 0
unsigned char delete_node(node *head, node *old_node)
{
    // Check if the node is exist or not
    if (old_node == NULL)
    {
        return 1;
    }

    node *back = head;

    // If delete the first node ONLY
    if (head == old_node)
    {
        free(old_node);
        old_node = NULL;
        return 0;
    }

    while (back -> next != old_node)
    {
        back = back -> next;
    }

    back -> next = old_node -> next;
    free(old_node);

    return 0;
}

// destroy the whole linked list, returns 0 if destroid successfully else number NOT 0
unsigned char destroy(node *head)
{
    // Check if the List is exist or not
    if (head == NULL)
    {
        return 1;
    }

    node *temp = head;

    while (temp != NULL)
    {
        temp = temp -> next;
        destroy(temp);
        delete_node(head, temp);

    }

    delete_node(head, head);

    return 0;
}

// return Pointer to node if founded it else return NULL
node *search(node *head, int value)
{
    while (head != NULL)
    {
        // If founded it return it's pointer
        if (head -> value == value)
        {
            return head;
        }
        else
        {
            head = head -> next;
        }
    }
    return NULL;
}

最佳答案

我不知道问题出在哪里,但我确实观察到您的 distroy (sic...) 函数不必要地复杂。如果您的目的是销毁整个列表,则无需调用 destroy_node 例程。只需执行以下操作:(伪代码...)

while (head != NULL) {
   temp = head->next;
   free(head);
   head = temp;
}

您的destroy_node例程看起来也不必要地复杂。只需考虑两种情况:删除 head 节点,以及删除不是头节点的节点。 (伪代码)

if (node == NULL) return;
if (node == head_node) {
   head_node = head_node->next;
   free(node);
} else {
   temp = head_node;
   while ((temp != NULL) {
     if (temp->next == node) {
        temp->next = temp->next->next;  // link it out of the list
        free(node);
        return;
     } else {
        temp = temp->next;
     }
  }
}

关于c - 为什么这个销毁函数在单链表中抛出段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60216885/

相关文章:

C指针上的指针: unused variable

python - Pandas:将行附加到列中具有多索引的DataFrame

c - 用 C 编写的低级问题的示例解决方案

c - 使用 C 开始使用 wpa_supplicant

c - 调试时得到 "?"问号而不是特殊符号

c++ - 创建一批随机矩阵

c - 即时调整 char* 的大小 - 为什么此代码*有效*?

c++ - 计算斯特林数的动态规划方法

c++ - 在索引和值类型上参数化的惯用 vector 类型

c++ - 解决运算符歧义