Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么这个销毁函数会在单链表中抛出分段错误_C_Pointers_Data Structures_Segmentation Fault - Fatal编程技术网

C 为什么这个销毁函数会在单链表中抛出分段错误

C 为什么这个销毁函数会在单链表中抛出分段错误,c,pointers,data-structures,segmentation-fault,C,Pointers,Data Structures,Segmentation Fault,我不熟悉数据结构和C。这段代码在创建和插入节点时正常工作,但当我调用destroy函数时,它的情况是一个分段错误。如果我将所有代码放在主函数中而不是其他函数中,它似乎正常工作 此错误是什么情况: •销毁 •删除如果仅删除链接列表的标题 谁能给我解释一下有什么问题吗 #include <stdio.h> #include <stdlib.h> typedef struct node { int value; struct node *next; } nod

我不熟悉数据结构和C。这段代码在创建和插入节点时正常工作,但当我调用destroy函数时,它的情况是一个
分段错误
。如果我将所有代码放在主函数中而不是其他函数中,它似乎正常工作

此错误是什么情况:

销毁

删除
如果仅删除链接列表的标题

谁能给我解释一下有什么问题吗

#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;
}
#包括
#包括
类型定义结构节点
{
int值;
结构节点*下一步;
}节点;
节点*创建_节点(int值);
无符号字符插入(节点*头,int值);
无符号字符删除节点(节点*头,节点*旧节点);
节点*搜索(节点*头部,int值);
未签名字符销毁(节点*头);
内部主(空)
{
节点*头=创建_节点(1);
插入(头,3);
插入(头,2);
销毁(头);
对于(节点*i=head;i!=NULL;i=i->next)
{
printf(“%i\n”,i->value);
}
}
//将创建一个节点并返回它,如果成功,否则将返回NULL
节点*创建_节点(int值)
{
node*new_node=malloc(sizeof(node));
//检查节点是否成功创建
if(新节点==NULL)
{
返回NULL;
}
新建_节点->值=值;
新建节点->下一步=空;
返回新的_节点;
}
//将节点插入到列表的开头,如果成功,则返回0,否则编号不是0
无符号字符插入(节点*头,int值)
{
节点*新建节点=创建节点(值);
//检查节点是否成功创建
if(新节点==NULL)
{
返回1;
}
//检查列表是否存在
if(head==NULL)
{
返回2;
}
新建节点->下一步=头部->下一步;
head->next=新建_节点;
返回0;
}
//删除节点,如果成功则返回0,否则编号不是0
无符号字符删除节点(节点*头,节点*旧节点)
{
//检查节点是否存在
if(旧节点==NULL)
{
返回1;
}
节点*背部=头部;
//如果仅删除第一个节点
if(head==旧节点)
{
空闲(旧节点);
old_node=NULL;
返回0;
}
while(后退->下一步!=旧节点)
{
后退=后退->下一步;
}
后退->下一步=旧节点->下一步;
空闲(旧节点);
返回0;
}
//销毁整个链表,如果destroid成功,则返回0,否则编号不是0
未签名字符销毁(节点*头)
{
//检查列表是否存在
if(head==NULL)
{
返回1;
}
节点*温度=头部;
while(temp!=NULL)
{
温度=温度->下一步;
销毁(临时);
删除_节点(头部、温度);
}
删除_节点(head,head);
返回0;
}
//返回指向节点的指针,否则返回NULL
节点*搜索(节点*头,int值)
{
while(head!=NULL)
{
//如果找到它,则返回它的指针
如果(头->值==值)
{
回流头;
}
其他的
{
头部=头部->下一步;
}
}
返回NULL;
}

我不知道问题到底出在哪里,但我确实注意到您的
发行版(原文如此…)功能过于复杂。如果您的目的是销毁整个列表,则不需要调用
destroy\u节点
例程。只需这样做:(伪代码…)

您的
destroy_节点
例程看起来也非常复杂。只有两种情况需要考虑:删除
头部
节点和删除非头部节点的节点。(伪代码)


你的问题是:

while (temp != NULL)
{
   temp = temp -> next;
   delete_node(head, temp);
}  
您的函数
删除\u节点(节点*头,节点*旧\u节点)
最后执行:

free(old_node); // you free temp !
并且您不会将
old_node
设置为
NULL
如果您释放了此内存,则无法在此处再次循环(因为临时已删除):


快速样式点,不要在指针声明
节点*head
的两侧都加空格,看起来您正试图将它们相乘。seg故障发生在哪一行代码上?在调试器中运行该程序将立即提供该信息。进入调试器后,您可以转储更多状态并跟踪程序执行以帮助查找问题。此外,还缺少一些代码,如
create\u node
insert
。请求调试帮助的所有堆栈溢出问题都需要一个。否则,您可能会遗漏一些实际导致问题的代码,并使其他人很难运行代码来查看/调试问题。由于错误,我使用了
delete\u node
,而不是
destroy
,我计划使用递归算法。但无论如何,修复代码后,错误仍然存在。@OmarAhmed你能更新你的代码(在帖子中)吗?请查看你所做的修改
while (temp != NULL)
{
   temp = temp -> next;
   delete_node(head, temp);
}  
free(old_node); // you free temp !
while (temp != NULL)
{
   temp = temp -> next;
   delete_node(head, temp);
}