以下是将新节点添加到升序链表的程序。
以下程序中存在导致segmentation Fault
的错误,我使用gdb
找出了细分错误的原因。
但我没有得到reason
的分段错误。任何人都可以说出分段错误的原因。
#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 -> data <= num && ( temp -> link -> data > num || temp -> link == NULL ))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
到
if ( temp -> data <= num && ( temp -> link == NULL || temp -> link -> data > num ))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
以上改变的工作就像一个魅力但是我得到了这种变化背后的理由。
帮助我找出原因
**已更新
如果短路评估是真正的原因那么下面的程序为何会起作用
int main()
{
int a=10,b=1,c=0;
int d;
d = (a && (c || b));
printf("%d",d);
getchar();
}
答案 0 :(得分:1)
表达式
temp -> link -> data > num || temp -> link == NULL
将首先评估逻辑的左侧,或者如果它是假的,则将评估右侧。这意味着如果temp->link
为NULL
,那么当您取消引用NULL
指针时,您就会undefined behavior。
更改的作用是更改逻辑或表达式中两个子表达式的评估顺序,因此首先检查temp->link
不是NULL
,然后取消引用temp->link
。
答案 1 :(得分:1)
当你这样做时 -
if ( temp -> data <= num && ( temp -> link -> data > num || temp -> link == NULL ))
在temp -> link -> data
中,如果temp -> link
等于或temp -> link
为NULL
,则表示此表达式为NULL -> data
。您正试图取消引用NULL。所以你会得到segmentation fault
。
if ( temp -> data <= num && ( temp -> link == NULL || temp -> link -> data > num ))
在这种情况下,您不会出现分段错误。因为当temp -> link
NULL
条件成立时,程序执行进入循环体。所以你不会在这里得到segmentation fault
。但是当temp -> link
不是NULL
时,它会取消引用它。
答案 2 :(得分:0)
在if语句的第二个版本中,short-circuit evaluation将确保temp->link
永远不会被解除引用。