C 以下链表程序分段错误的根本原因是什么?
下面是向升序链表添加新节点的程序 下面的程序中有一个bug,导致了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 (
分段错误
我使用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 ))