-1

Hey I am trying to understand pointers and I noticed something which causes undefined behavior in my program In first case when I decay pointer to q1 to NULL everything is fine but when I decay pointer *q1 to NULL the terminal does not show anything . What is going wrong?

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



int main ()
{
    char *p[11]={"vasilis","loukas","vasilis","vasilis","giorgos","makis","vasilis","nikos","makis","nikos"};
    
    
    char **p1;
    char**d1;
    char**q1;
    q1=NULL;
    p1=&p[0];
    d1=&p[1];
    
    
    
    /******Count words*********/
    int count=0;
    
    for(p1=&p[0] ; *p1 ; p1++)
    {
        count++;
        }
    
    
    printf("\nthe number of words : %d" ,count);
    
    return 0;
}

second case :

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



int main ()
{
    char *p[11]={"vasilis","loukas","vasilis","vasilis","giorgos","makis","vasilis","nikos","makis","nikos"};
    
    
    char **p1;
    char**d1;
    char**q1;
    *q1=NULL;
    p1=&p[0];
    d1=&p[1];
    
    
    
    /******Count words*********/
    int count=0;
    
    for(p1=&p[0] ; *p1 ; p1++)
    {
        count++;
        }
    
    
    printf("\nthe number of words : %d" ,count);
    
    return 0;
}
vgag1997
  • 31
  • 1
  • 1
    You don't "decay" a pointer to `NULL`, you *assign* `NULL` to a pointer (just like you assign integer values to `int` variables). And `*q1` dereferences the `q1` pointer. Which can only be done if the pointer is already pointing somewhere valid. In fact, `*q1` is *exactly* the same as `q1[0]`. – Some programmer dude May 26 '21 at 15:42
  • in the 2nd case `*q1 = NULL`, you are assigning `NULL` to some random place in memory. Behavior would be undefined and could also result in Segfault. One more thing `*p1`, C doesn't support array-bound checking so your loop could also end up showing some weird behavior. – Shubham May 26 '21 at 15:44
  • 2
    As a quick and simple way to learn how pointers works, take a pen and some paper. Then draw a long box for `p`, and divide it into `11` parts. Draw arrows from each part and end them with the strings in the array. Now draw three new boxes, and label them `p1`, `d1` and `q1`. Draw arrows to the places where they point (i.e. `p1` should have an arrow to `p[0]`). For the assignment `q1 = NULL` (note *no* dereference operator) draw an arrow into empty space and just label it `NULL`. For the second example *don't* draw an arrow for ``q1`, because it doesn't point anywhere. Hope that helps. – Some programmer dude May 26 '21 at 15:45
  • @Someprogrammerdude Ok I understand what you say but why here https://www.geeksforgeeks.org/linked-list-set-2-inserting-a-node/?ref=lbp in the case : /* Given a reference (pointer to pointer) to the head of a list and an int, appends a new node at the end */ I can assign if (*head == NULL) I know it is completely different project but why in this case I can assign NULL? – vgag1997 May 26 '21 at 15:54
  • Then `head` is actually pointing somewhere valid (probably by using the address-of or pointer-to operator `&` to create a pointer to a pointer variable). – Some programmer dude May 26 '21 at 15:55

1 Answers1

0

In your first code, the q1 = NULL; line is assigning a zero (null) value to the pointer, q1, which is a perfectly valid operation (even though that pointer potentially points to another pointer). In fact, assigning a NULL value to a pointer is a common technique, used so that code can test whether or not that pointer currently contains a valid address or not (if it's NULL, then we can't use it).

In your second code, *q1 = NULL;, you are trying to assign zero to the object (itself a pointer) that is pointed-to by q1; however, q1 hasn't been assigned a value (an address), so it doesn't point to any valid target, and your attempt fails (because you are trying to modify a 'random' part of memory that you likely don't have access to).

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83