Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.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_Linked List_Singly Linked List - Fatal编程技术网

C 以下链表程序分段错误的根本原因是什么?

C 以下链表程序分段错误的根本原因是什么?,c,linked-list,singly-linked-list,C,Linked List,Singly Linked List,下面是向升序链表添加新节点的程序 下面的程序中有一个bug,导致了分段错误我使用gdb找出了分段错误的原因 但是我没有得到分段错误的原因。谁能说出分割错误的原因 #include<stdio.h> #include<stdlib.h> struct node { int data ; struct node *link ; } ; void add ( struct node **, int ) ; void display (

下面是向升序链表添加新节点的程序

下面的程序中有一个bug,导致了
分段错误
我使用
gdb
找出了分段错误的原因

但是我没有得到分段错误的原因。谁能说出分割错误的原因

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

  struct node
 {
     int data ;
     struct node *link ;
 } ;

 void add ( struct node **, int ) ;
 void display ( struct node * ) ;

 int  main( )
{
       struct node *p ;
        p = NULL ;  

    add ( &p, 5 ) ;
    add ( &p, 1 ) ;
    add ( &p, 6 ) ;
    add ( &p, 4 ) ;
    add ( &p, 7 ) ;


    display ( p ) ;

}


void add ( struct node **q, int num )
{
    struct node *r, *temp = *q ;

    r = ( struct node *)  malloc ( sizeof ( struct node ) ) ;
    r -> data = num ;


  if ( *q == NULL || ( *q ) -> data > num )
 {
    *q = r ;
    ( *q ) -> link = temp ;
 }
 else
 {
    while ( temp != NULL )
    {
        if ( temp -> data <= num && ( temp -> link -> data > num || 
                                    temp -> link == NULL ))
        {
            r -> link = temp -> link ;
            temp -> link = r ;
            return ;
        }
        temp = temp -> link ;  
    }
  }
}


void display ( struct node *q )
{
    printf ( "\n" ) ;


    while ( q != NULL )
    {
        printf ( "%d ", q -> data ) ;
       q = q -> link ;
    }
}

在if语句的第二个版本中,将确保从未取消引用
temp->link

表达式

temp -> link -> data > num || temp -> link == NULL
将首先计算逻辑or的左侧,如果为false,则将计算右侧。这意味着,如果
temp->link
NULL
,那么您就可以取消引用
NULL
指针

更改的作用是更改逻辑or表达式中两个子表达式的求值顺序,因此它首先检查
temp->link
是否为
NULL
,然后在这样做时取消引用
temp->link

-

if ( temp -> data <= num && ( temp -> link -> data > num || temp -> link == NULL ))

在这种情况下,不会出现分段错误。因为当
temp->link
NULL
时,条件变为true,程序执行进入循环体。所以你不会在这里得到分段错误。但是当
temp->link
不是
NULL
时,它将取消对它的引用。

您使用过任何调试器吗?因为布尔运算符执行“短路”求值。gdb用于调试,并且其停止@已更改line@pmg在int main()的情况下,{int a=10,b=1,c=0;int d;d=(a&&(c|b));printf(“%d”,d);getchar();}在这种情况下,这个程序应该产生0,对吗?您正在解引用
temp->link
,而没有检查它是否为NULL,因此是一个segfault。在第二种情况下,检查它是否为NULL,如果为NULL。
      int main()
     {

       int a=10,b=1,c=0;
       int d;
       d = (a && (c || b));

       printf("%d",d);
      getchar();
      }
temp -> link -> data > num || temp -> link == NULL
if ( temp -> data <= num && ( temp -> link -> data > num || temp -> link == NULL ))
if ( temp -> data <= num && ( temp -> link == NULL || temp -> link -> data > num  ))