C 当我尝试从链表中删除元素时,会出现分段错误

C 当我尝试从链表中删除元素时,会出现分段错误,c,struct,singly-linked-list,erase,function-definition,C,Struct,Singly Linked List,Erase,Function Definition,我是一个乞丐,正在努力学习数据结构。我写了一个代码,从链表中删除一个元素。如果元素alreay存在于列表中,则在编译和运行期间不会发生任何问题。但是,当我试图删除列表中不存在的元素时,即使我已经编写了代码,也会出现分段错误。你能帮我看看吗 #include <stdio.h> #include <stdlib.h> typedef struct node { int x; struct node *next; }node; void addElement

我是一个乞丐,正在努力学习数据结构。我写了一个代码,从链表中删除一个元素。如果元素alreay存在于列表中,则在编译和运行期间不会发生任何问题。但是,当我试图删除列表中不存在的元素时,即使我已经编写了代码,也会出现分段错误。你能帮我看看吗

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
    int x;
    struct node *next;
}node;

void addElement(node *r, int x)
{
    for(; r->next!=NULL; r=r->next);
    r->next=(node*)malloc(sizeof(node));
    r->next->x=x;
    r->next->next=NULL;

}
node* add_Element_inorder(node *r, int x)
{
    if(r==NULL)
    {
        r=(node*)malloc(sizeof(node));
        r->next=NULL;
        r->x=x;
        return r;
    }
    if(r->x>x)
    {
        node*tmp=(node*)malloc(sizeof(node));
        tmp -> x = x;
        tmp->next=r;
        return tmp;
    }
    node *iter=r;

    while(iter->next!=NULL && iter->next->x < x)
    {

        iter=iter->next;
    }

    node*tmp=(node*)malloc(sizeof(node));
    tmp->next = iter->next;
    iter->next=tmp;
    tmp->x=x;
    return r;

}
void print_Linked_L(node *r)
{
    node* iter = r;
    printf("%d ", iter->x);
    iter=iter->next;
    while(iter != NULL)
    {
        printf("%d ", iter->x);
        iter=iter->next;
    }

}
node* erase_Element(node *r, int x)
{
   node*iter=r;
   if(iter->x == x)
   {
       r=r->next;
       free(iter);
       return r;
   }

   while(iter->next->x != x && iter->next!=NULL)
   {
       iter=iter->next;

   }

    if(iter->next==NULL)
    {
        printf("Number does not exist.");
        return r;
    }

   node *temp=iter->next;
   iter->next=iter->next->next;
   free(temp);
   return r;
}

int main()
{

    node *root = (node*)malloc(sizeof(node));
    root=NULL;
    root= add_Element_inorder(root, 400);
    root= add_Element_inorder(root, 40);
    root= add_Element_inorder(root, 4);
    root= add_Element_inorder(root, 450);
    root= add_Element_inorder(root, 50);
    node *iter=root;
    print_Linked_L(root);
    root =erase_Element(root,45);
    printf("\n");
    print_Linked_L(root);







return 0;
}
#包括
#包括
类型定义结构节点
{
int x;
结构节点*下一步;
}节点;
无效加法元素(节点*r,整数x)
{
对于(;r->next!=NULL;r=r->next);
r->next=(node*)malloc(sizeof(node));
r->next->x=x;
r->next->next=NULL;
}
节点*按顺序添加元素(节点*r,整数x)
{
if(r==NULL)
{
r=(节点*)malloc(sizeof(节点));
r->next=NULL;
r->x=x;
返回r;
}
如果(r->x>x)
{
node*tmp=(node*)malloc(sizeof(node));
tmp->x=x;
tmp->next=r;
返回tmp;
}
节点*iter=r;
while(iter->next!=NULL&&iter->next->xnext;
}
node*tmp=(node*)malloc(sizeof(node));
tmp->next=iter->next;
iter->next=tmp;
tmp->x=x;
返回r;
}
无效打印链接(节点*r)
{
节点*iter=r;
printf(“%d”,iter->x);
iter=iter->next;
while(iter!=NULL)
{
printf(“%d”,iter->x);
iter=iter->next;
}
}
节点*擦除元素(节点*r,整数x)
{
节点*iter=r;
如果(iter->x==x)
{
r=r->next;
免费(iter);
返回r;
}
while(iter->next->x!=x&&iter->next!=NULL)
{
iter=iter->next;
}
如果(iter->next==NULL)
{
printf(“数字不存在”);
返回r;
}
节点*temp=iter->next;
iter->next=iter->next->next;
免费(临时);
返回r;
}
int main()
{
node*root=(node*)malloc(sizeof(node));
root=NULL;
根=按顺序添加元素(根,400);
根=按顺序添加元素(根,40);
根=按顺序添加元素(根,4);
root=按顺序添加元素(root,450);
根=按顺序添加元素(根,50);
节点*iter=根;
打印链接(根);
根=删除元素(根,45);
printf(“\n”);
打印链接(根);
返回0;
}
在这段代码中,首先运行iter->next->x,然后运行iter->next=无效的 您取消引用空值。 解决办法是:

while(iter->next!=NULL && iter->next->x != x )

事实上,所有的功能都是不正确的

例如,在这个函数中

void addElement(node *r, int x)
{
    for(; r->next!=NULL; r=r->next);
    r->next=(node*)malloc(sizeof(node));
    r->next->x=x;
    r->next->next=NULL;

}
不检查t是否等于NULL。函数的定义至少应类似于

node * addElement( node *head, int x )
{
    node *new_node = malloc( sizeof( node ) );
    new_node->x = x;

    if ( head == NULL )
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;

        while ( current->next != NULL ) current = current->next;

        new_node->next = NULL;
        current->next = new_node;
    }

    return head;
}    
在函数
add_Element\u In order
中有两个重复的代码。可以更简单地定义该函数

node * add_Element_inorder( node *head, int x)
{
    node *new_node = malloc( sizeof( node ) );
    new_node->x = x;

    if ( head == NULL || x < head->x )
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;

        while ( current->next != NULL && !( x < current->next->x ) )
        {
            current = current->next;
        }

        new_node->next = current->next;
        current->next = new_node;
    }

    return head;
}
该函数可以定义为

void print_Linked_L( const node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->x );
    }

    puts( "null" );
}
由于while语句中的条件顺序不正确,当没有具有目标值的节点时,函数
erase\u元素可以再次调用未定义的行为

while(iter->next->x != x && iter->next!=NULL)
首先,您需要检查
iter->next!=空
,然后检查其值是否不等于x

该函数可以通过以下方式定义

node * erase_Element( node *head, int x )
{
    if ( head != NULL )
    {
        if ( head->x == x )
        {
            node *tmp = head;
            head = head->next;
            free( tmp );
        }
        else
        {
            node *current = head;

            while ( current->next != NULL && current->next->x != x )
            {
                current = current->next;
            }

            if ( current->next != NULL )
            {
                node *tmp = current->next;
                current->next = current->next->next;
                free( tmp );
            }
            else
            {
                printf( "Number %d does not exist in the list.\n", x );
            }   
        }
    }

    return head;
}
函数main以内存泄漏开始

int main()
{
    node *root = (node*)malloc(sizeof(node));
    root=NULL;
首先分配内存,然后立即由于覆盖指针根而丢失返回的地址

下面是一个演示程序,显示了更新的函数定义

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

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

node * addElement( node *head, int x)
{
    node *new_node = malloc( sizeof( node ) );
    new_node->x = x;

    if ( head == NULL )
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;

        while ( current->next != NULL ) current = current->next;

        new_node->next = NULL;
        current->next = new_node;
    }

    return head;
}    

node * add_Element_inorder( node *head, int x)
{
    node *new_node = malloc( sizeof( node ) );
    new_node->x = x;

    if ( head == NULL || x < head->x )
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;

        while ( current->next != NULL && !( x < current->next->x ) )
        {
            current = current->next;
        }

        new_node->next = current->next;
        current->next = new_node;
    }

    return head;
}

void print_Linked_L( const node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->x );
    }

    puts( "null" );
}

node * erase_Element( node *head, int x )
{
    if ( head != NULL )
    {
        if ( head->x == x )
        {
            node *tmp = head;
            head = head->next;
            free( tmp );
        }
        else
        {
            node *current = head;

            while ( current->next != NULL && current->next->x != x )
            {
                current = current->next;
            }

            if ( current->next != NULL )
            {
                node *tmp = current->next;
                current->next = current->next->next;
                free( tmp );
            }
            else
            {
                printf( "Number %d does not exist in the list.\n", x );
            }   
        }
    }

    return head;
}

int main(void) 
{
    node *root = NULL;

    root = add_Element_inorder( root, 400 );
    root = add_Element_inorder( root, 40 );
    root = add_Element_inorder( root, 4 );
    root = add_Element_inorder( root, 450 );
    root = add_Element_inorder( root, 50 );

    print_Linked_L( root );

    root = erase_Element( root, 45 );
    print_Linked_L(root);   
    root = erase_Element( root, 400 );
    print_Linked_L(root);   
    root = erase_Element( root, 40 );
    print_Linked_L(root);   
    root = erase_Element( root, 4 );
    print_Linked_L(root);   
    root = erase_Element( root, 450 );
    print_Linked_L(root);   
    root = erase_Element( root, 50 );
    print_Linked_L(root);   

    return 0;
}

使用调试器比在线提问更能有效地解决这个问题。@Yekta Yüksel您选择了一个错误的答案作为最佳答案。请注意,我的答案才是最好的。:)
int main()
{
    node *root = (node*)malloc(sizeof(node));
    root=NULL;
#include <stdio.h>
#include <stdlib.h>

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

node * addElement( node *head, int x)
{
    node *new_node = malloc( sizeof( node ) );
    new_node->x = x;

    if ( head == NULL )
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;

        while ( current->next != NULL ) current = current->next;

        new_node->next = NULL;
        current->next = new_node;
    }

    return head;
}    

node * add_Element_inorder( node *head, int x)
{
    node *new_node = malloc( sizeof( node ) );
    new_node->x = x;

    if ( head == NULL || x < head->x )
    {
        new_node->next = head;
        head = new_node;
    }
    else
    {
        node *current = head;

        while ( current->next != NULL && !( x < current->next->x ) )
        {
            current = current->next;
        }

        new_node->next = current->next;
        current->next = new_node;
    }

    return head;
}

void print_Linked_L( const node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->x );
    }

    puts( "null" );
}

node * erase_Element( node *head, int x )
{
    if ( head != NULL )
    {
        if ( head->x == x )
        {
            node *tmp = head;
            head = head->next;
            free( tmp );
        }
        else
        {
            node *current = head;

            while ( current->next != NULL && current->next->x != x )
            {
                current = current->next;
            }

            if ( current->next != NULL )
            {
                node *tmp = current->next;
                current->next = current->next->next;
                free( tmp );
            }
            else
            {
                printf( "Number %d does not exist in the list.\n", x );
            }   
        }
    }

    return head;
}

int main(void) 
{
    node *root = NULL;

    root = add_Element_inorder( root, 400 );
    root = add_Element_inorder( root, 40 );
    root = add_Element_inorder( root, 4 );
    root = add_Element_inorder( root, 450 );
    root = add_Element_inorder( root, 50 );

    print_Linked_L( root );

    root = erase_Element( root, 45 );
    print_Linked_L(root);   
    root = erase_Element( root, 400 );
    print_Linked_L(root);   
    root = erase_Element( root, 40 );
    print_Linked_L(root);   
    root = erase_Element( root, 4 );
    print_Linked_L(root);   
    root = erase_Element( root, 450 );
    print_Linked_L(root);   
    root = erase_Element( root, 50 );
    print_Linked_L(root);   

    return 0;
}
4 -> 40 -> 50 -> 400 -> 450 -> null
Number 45 does not exist in the list.
4 -> 40 -> 50 -> 400 -> 450 -> null
4 -> 40 -> 50 -> 450 -> null
4 -> 50 -> 450 -> null
50 -> 450 -> null
50 -> null
null