0

Below is the Program to add a new node to the ascending order linked list.

There was bug in below program which causing segmentation Fault I figured out the cause for segmentation Fault using gdb.

But i did not get what is reason for segmentation Fault. Can anyone tell reason for segmentation Fault.

  #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 ;
    }
}

I changed the order in this line from

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

to

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

The above changed work like a charm But i dint get reason behind this changes.

So help me to figure out the reason

**Updated

If short-circuit evalution is real cause then why this below program works

      int main()
     {

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

       printf("%d",d);
      getchar();
      }
vinay hunachyal
  • 3,781
  • 2
  • 20
  • 31

3 Answers3

1

The expression

temp -> link -> data > num || temp -> link == NULL

will first evaluate the left hand side of the logical or, and if it's false then the right hand side will be evaluated. That means if temp->link is NULL then you have undefined behavior as you dereference a NULL pointer.

What the change does is that it changes the evaluation order of the two sub-expressions in the logical or expression, so it first check temp->link not being NULL, and then dereferences temp->link.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

When you do like this-

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

In temp -> link -> data, If temp -> link is equal to or when temp -> link is NULL means this expression becomes NULL -> data. you are trying to dereferencing NULL. so you will get segmentation fault.

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

In this case you won't get segmentation fault. because when temp -> link is NULL condition becomes true, Program execution enters into the body of the loop. So you wont get segmentation fault here. But when temp -> link is not NULL then it will dereference it.

Sathish
  • 3,740
  • 1
  • 17
  • 28
0

In the second version of the if statement, short-circuit evaluation will make sure that temp->link is never dereferenced.

Tom Moers
  • 1,243
  • 8
  • 13