This blog is under construction

Tuesday, 5 November 2013

Dangling pointers

What is dangling pointer?
If a pointer refers to an invalid memory location, then it is called dangling pointer. Consider any pointer that points to a newly allocated memory block.  If the newly allocated block is freed without modifying the pointer value, then the pointer will point to the deallocated memory block.  So, corruption might occur if the user tries to perform write operation in the memory block pointed by dangling pointer.  In most cases, user can observe segmentation fault when he tries to free/dereference a dangling pointer.

      int *ptr , *tmp;
      ptr = (int *)malloc(sizeof(int));
      tmp = ptr;
      free(ptr);
      *tmp = *tmp + 10
Here, tmp is a dangling pointer since it points to the freed memory block.

Below is an another example for dangling pointer.

      int *ptr;
     {
             int ch = 10;
             ptr = &ch;
             printf("%d", *ptr);
      }
      /* ch is out of scope, but pointer "ptr" holds invalid reference */
     if (ptr) {
            *ptr = *ptr + 1;
     }

The scope of the variable ch is limited to the block in which it is declared.  So, ptr is a dangling pointer since it has an invalid reference.

Below is the simple program that illustrates the impact of dangling pointers.


  #include <stdio.h>
  #include <stdlib.h>
  int main() {
        int i, n, *ptr, *tmp;

        /* get the number of inputs from the user */
        printf("Enter number of inputs:");
        scanf("%d", &n);

        /* dynamic memory allocation for n integers */
        ptr = (int *)malloc(sizeof(int) * n);

        /* get the inputs from the user */
        printf("Enter your inputs:\n");
        for (i = 0; i < n; i++) {
                scanf("%d", ptr + i);
        }

        /* assign the referece in ptr to tmp */
        tmp = ptr;
        free(ptr);  // freed newly allocated block */

        /* process and freeing dangling pointer tmp */
        if (tmp) {
                for (i = 0; i < n; i++) {
                        printf("%d ", *(tmp + i));
                }
                free(tmp);
        }
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Enter number of inputs:5
  Enter your inputs:
  10 20 30 40 50
  *** glibc detected *** ./a.out: double free or corruption (fasttop): 0x08825008 ***
  ======= Backtrace: =========
  /lib/libc.so.6(+0x6c0c1)[0x8590c1]
  /lib/libc.so.6(+0x6d930)[0x85a930]
  /lib/libc.so.6(cfree+0x6d)[0x85da1d]
  ./a.out[0x8048583]
  /lib/libc.so.6(__libc_start_main+0xe7)[0x803ce7]
  ./a.out[0x8048411]


The above program got terminated due to the invalid reference in dangling pointer.


How to avoid dangling pointer?
In order to avoid dangling pointers problem, set the pointer to NULL after freeing the memory block.  So that, pointer won't point to the invalid(freed) memory block.

          int *ptr , *tmp;
         ptr = (int *)malloc(sizeof(int));
         tmp = ptr;
         free(ptr);
         ptr = tmp = NULL;

Now, tmp is not a dangling pointer since its value is set to NULL after deallocation.

         int *ptr;
        {
               int ch = 10;
               ptr = &ch;
              printf("%d", *ptr);
              ptr = NULL;
       }
       if (ptr) {
             *ptr = *ptr + 1;
       }


Now, ptr is not a dangling pointer since its value is set to NULL before the local variable ch goes out of scope.

Sort n numbers in ascending order using pointers

C program to sort n numbers in ascending order using pointers


  #include <stdio.h>
  #include <stdlib.h>
  int main() {
        int i, j, n, tmp, *ptr;
        /* get the number of inputs from the user */
        printf("Enter number of inputs:");
        scanf("%d", &n);

        /* dynamic memory allocation for n elements */
        ptr = (int *)malloc(sizeof(int) * n);

        /* get the inputs from the user */
        printf("Enter your inputs:\n");
        for (i = 0; i < n; i++) {
                scanf("%d", ptr + i);
        }

        /* sort the given numbers in ascending order */
        for (i = 0; i < n - 1; i++) {
                for (j = i + 1; j < n; j++) {
                        if (*(ptr + i) > *(ptr + j)) {
                                tmp = *(ptr + i);
                                *(ptr + i) = *(ptr + j);
                                *(ptr + j) = tmp;
                        }
                }
        }

        /* prints the sorted numbers */
        printf("Output:\n");
        for (i = 0; i < n; i++) {
                printf("%d ", *(ptr + i));
        }
        printf("\n");

        /* release the dynamically allocated memory */
        free(ptr);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Enter number of inputs: 5
  Enter your inputs:
  99  29  34  14  25
  Output:
  14  25  29  34  99 


Pointer to union

Union pointers:
What is pointer to union?
If the pointer refers to the address of the union variable, then the pointer is called  pointer to union or union pointer.
     union val {
             int ival;
             float fval;
             char cval;
     } obj, *ptr;

     ptr = &obj;


Here, pointer ptr refers to the address of the union variable obj.

How to access and assign values to union elements using pointers?
Dereference operator "->" is used to access and assign values to union using pointers.
       ptr->ival = 10;
       ptr->fval = 20.22;
       ptr->cval = 'a';
Note: Only one data member will be active at a time.
The above set of statements is equivalent to 
       (*ptr).ival = 10;
       (*ptr).fval = 20.22;
       (*ptr).cval = 'a';
Here, we have shown how to assign values to all data members of a union.  But, only one data member will be active at a time in union.  We have assigned value to (*ptr).cval recently.  So, its the current active data member in our case.


Passing union pointer as function argument
Like other data types, union pointer can also be passed as function argument.  Below program explains how to pass union pointer as function argument.

C program for pointer to union:

  #include <stdio.h>
  /* union with three different data members */
  union val {
        int ival;
        float fval;
        char cval;
  };

  /* updating data members of union using pointer */
  void update(union val *ptr, int flag) {
        if (flag == 0) {
                ptr->ival = 10;
        } else if (flag == 1) {
                ptr->fval = 10.22;
        } else {
                ptr->cval = 'z';
        }
        return;
  }

  int main() {
        int i;
        union val obj, *ptr;
        /* assigning address of union variable to pointer */
        ptr = &obj;

        for (i = 0; i < 3; i++) {
                update(ptr, i);
                /* printing the result */
                if (i == 0) {
                        printf("ptr->ival: %d\n", ptr->ival);
                } else if (i == 1) {
                        printf("ptr->fval: %.2f\n", ptr->fval);
                } else {
                        printf("ptr->cval: %c\n", ptr->cval);
                }
        }
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  ptr->ival: 10
  ptr->fval: 10.22
  ptr->cval: z



How to return union pointer from function?
Below program explains how to return union pointer from function.

C program for union pointers:
  #include <stdio.h>
  #include <stdlib.h>
  /* union with three different data members */
  union val {
        int ival;
        float fval;
        char cval;
  };

  /* updates data members of union and returns a pointer to union */
  union val * update(int flag) {
        union val *ptr;
        /* dynamic memory allocation for union */
        ptr = (union val *)malloc(sizeof(union val));

        /* updating values for union data members */
        if (flag == 0) {
                ptr->ival = 10;
        } else if (flag == 1) {
                ptr->fval = 10.22;
        } else {
                ptr->cval = 'z';
        }
        return(ptr);
  }

  int main() {
        int i;
        union val *ptr;

        for (i = 0; i < 3; i++) {
                ptr = update(i);
                /* printing the result */
                if (i == 0) {
                        printf("ptr->ival: %d\n", ptr->ival);
                } else if (i == 1) {
                        printf("ptr->fval: %.2f\n", ptr->fval);
                } else {
                        printf("ptr->cval: %c\n", ptr->cval);
                }
                /* releasing the memory */
                free(ptr);
        }
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  ptr->ival: 10
  ptr->fval: 10.22
  ptr->cval: z



Dynamic memory allocation for union:
Let us see how to perform dynamic memory allocation for a union.
     union val {
             int ival;
             float fval;
             char cval;
     } *ptr;
    ptr = (union val *)malloc(sizeof(union val));

The above statement performs dynamic memory allocation for a union object using pointers.

Monday, 4 November 2013

Pointers to structures

Structure pointers
What is structure pointer?
If the pointer refers to the address of the structure variable, then the pointer is called structure pointer or pointer to structure.
     struct student {
char name[32];
int rollno, marks[5];
float average;
     } obj, *ptr;

     ptr = &obj;

Here, pointer ptr refers to the address of the structure variable obj.

C program using structure pointer:


  #include <stdio.h>
  /* structure st with three different members */
  struct st {
        char ch;
        int num;
        float val;
  } obj, *ptr; // one structure object and a pointer to structure
    int main() {
        /* assigning address of structure variable to pointer */
        ptr = &obj;

        /* assigning values to structure elements using pointer */
        ptr->ch = 'a';
        ptr->num = 10;
        ptr->val = 20.22;

        /* printing the result */
        printf("obj.ch : %c\n", obj.ch);
        printf("obj.num: %d\n", obj.num);
        printf("obj.val: %.2f\n", obj.val);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  obj.ch : a
  obj.num: 10
  obj.val: 20.22



How to access and assign values to structure elements using pointers?
Structure dereference operator is used to assign value to or access structure elements.
          strcpy(ptr->name, "JP");
          ptr->rollno = 5;
          ptr->mark[0] = 100, ptr->mark[1] = 99;
          ptr->average = (100 + 98) / 2;

So, we have assigned values to structure elements using structure dereference operator. The above set of statements is equivalent to 
          strcpy((*ptr).name, "JP");
          (*ptr).rollno = 5;
         (*ptr).mark[0] = 100, (*ptr).mark[1] = 99;
         (*ptr).average = 99.5;

Passing structure pointer to function:
Like other data types, structure pointer can also be passed as function argument.  Below program explains how to pass structure pointer as function argument.


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

  /* structure with 4 data members */
  struct student {
        char name[32];
        int rollno, marks[2];
        float average;
  };

  /* updates value for the given structure object using pointer */
  void update(struct student *ptr) {
        strcpy(ptr->name, "Barack Obama");
        ptr->rollno = 110011;
        ptr->marks[0] = 99;
        ptr->marks[1] = 100;
        ptr->average = (ptr->marks[0] + ptr->marks[1]) / 2.0;
  }

  int main() {
        struct student obj;
        /* passing address of a structure variable as argument */
        update(&obj);

        /* printing the result */
        printf("Name: %s\n", obj.name);
        printf("Roll Number: %d\n", obj.rollno);
        printf("Marks in subject 1: %d\n", obj.marks[1]);
        printf("Marks in subject 2: %d\n", obj.marks[2]);
        printf("Average: %f\n", obj.average);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Name: Barack Obama
  Roll Number: 110011
  Marks in subject 1: 100
  Marks in subject 2: 1120337920
  Average: 99.500000



How to return structure pointer from function?
Below program explains how to return structure pointer from function.


  #include <stdio.h>
  #include <stdlib.h>
  struct op {
        int sum;
        float diff;
  };

  /* finds sum and diff with given input and returns structure pointer */
  struct op * calculate(int x1, int y1, float x2, float y2) {
        struct op *ptr;
        /* dynamic memory allocation for structure */
        ptr = (struct op *)malloc(sizeof(struct op));

        /* assigning values to structure elements */
        ptr->sum = x1 + y2;
        ptr->diff = x2 - y2;
        return ptr;
  }

  int main() {
        struct op *ptr; /* structure pointer declaration */
        ptr = calculate(10, 20, 40.33, 33.22);
        /* printing the result */
        printf("ptr->sum : %d\n", ptr->sum);
        printf("ptr->diff: %.2f\n", ptr->diff);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  ptr->sum : 43
  ptr->diff: 7.11



Dynamic memory allocation for structure:
Let us see how to perform dynamic memory allocation for a structure.
     struct student {
char name[32];
int rollno, marks[5];
float average;
     } *ptr;

    ptr = (struct student *)malloc(sizeof(struct student));

The above statement performs dynamic memory allocation for a structure object using pointers.

Sunday, 3 November 2013

Character pointer

Pointer to character:
What is character pointer?
If the base type of a pointer is a character, then the pointer is called character pointer or pointer to character.

How to declare character pointer?
Below is the declaration for character pointer.
          char *<variable_name>;
          char *ptr;

How to initialize character pointer in c?
Below are few examples for character pointer initialization.
     char *ptr = NULL;
     char *ptr = "Hello world";

What is the size of character pointer?
The size of character pointer can be obtained using the sizeof() operator


Program:

  #include <stdio.h>
  int main() {
        char *cptr;
        printf("Sizeof character pointer: %d bytes\n", sizeof(cptr));
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Sizeof character pointer: 4 bytes



How character pointer works?
Basically, a string is an array of characters terminated with null character '\0'.  And it can be accessed using pointer of type char.  Consider the below declarations.
          char str[16] = "Hello World";
          char *cptr;

Here, str is an character array and cptr is a character pointer.  Let us assign the base address of the array str to pointer cptr
          cptr = str;
Now, pointer cptr refers to the first character in the array str.

Below are few other ways to access characters in an array using pointers.
(cptr + i)  <=> &str[i]  // refers to ith element in array str
cptr[i]      <=> str[i]    // character at ith index of array str
*(cptr +i) <=> str[i]    // character at ith index of array str

How to print a string using pointers in c?
Below program explains how to print a string using character pointers.


  #include <stdio.h>
  int main() {
        char *cptr, str[32] = "Hello world";

        /* assigning base address of the array str */
        cptr = str;

        /* printing the output */
        printf("Input string: ");
        while (*cptr != '\0') {
                printf("%c", *cptr++);
        }

        printf("\n");
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Input string: Hello world



How to compare strings using character pointers?
Consider two characters pointers cptr1 and cptr2.  And they point to two different strings.
          char *cptr1 = "Hello world";
          char *cptr2 = "Hello world";
Let us check whether the strings pointed by two given pointers are same or not.


  #include <stdio.h>
  int main() {
        int flag = 0;
        char *cptr1 = "hello world";
        char *cptr2 = "hello world";

        /* checking whether the given 2 strings are same */
        while (*cptr1 == *cptr2) {
                if (!*cptr1 && !*cptr2) {
                        flag = 1;
                        break;
                }
                cptr1++, cptr2++;
        }

        /* printing the result */
        if (flag) {
                printf("Given two strings are same\n");
        } else {
                printf("Given two strings are not same\n");
        }
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Given two strings are same



How to pass character pointer as function argument? How to return character pointer?
Like other data types, character pointer can also be passed as function argument.  Below program explains how to pass character pointer as function argument and how to return character pointer.


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

  /* returns a string "hello world" to the caller */
  char * charPtr(char *src) {
        char *tmp, *dest, *ptr = "world";

        /* dynamic memory allocation */
        dest = (char *)calloc(32, sizeof(char));

        tmp = dest;

        /* copying hello in src to dest pointer */
        while (*src) {
                *dest = *src;
                src++, dest++;
        }

        /* appending space */
        *dest++ = ' ';

        /* copying the string "world" */
        while (*ptr) {
                *dest = *ptr;
                ptr++, dest++;
        }

        /* null termination */
        *dest = '\0';
        dest = tmp;

        /* returning null pointer */
        return (dest);
  }

  int main() {
        char *cptr1, *cptr2 = "Hello";
        /* passing character pointer as argument */
        cptr1 = charPtr(cptr2);
        printf("Ouput: %s\n", cptr1);

        /* release the dynamically allocated block */
        free(cptr1);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Ouput: Hello world


Pointer to pointer

Pointer is a variable that stores address of another variable.  Whereas, pointer to pointer is nothing but a variable that stores the address of another pointer.

Below is the declaration for pointer to pointer
      <datatype>  **<variable_name>
      char **ptr;  // pointer to pointer to char

Let us see how pointer to pointer works.  Consider the below example
       char ch = 'a';
       char *cptr, **dptr;
       cptr = &ch;  // pointer stores address  of other variable
       dptr = &cptr;  // pointer to pointer stores address of another pointer

dptr     - address of cptr
*dptr   - address of the variable ch
**dptr - value in ch which is 'a'

Pointer to pointer is also called as double pointer.  Let us see how to do memory allocation for double pointer.

Dynamic memory allocation for double pointer:
       int i, **ptr;
       ptr = (int **)malloc(sizeof(int) * 3);
      for (i = 0; i < 3; i++) {
     ptr[i] = (int *) malloc(sizeof(int) * 4);
      }

So, above set of statements is equivalent to an integer array with 3 rows and 4 columns.

Let us see a simple program on double pointer.


  #include <stdio.h>
  int main() {
        int num = 10, *ptr, **dptr;

        /* initializing pointers with valid addresses */
        ptr = &num;
        dptr = &ptr;

        /* printing outputs */
        printf("dptr  : 0x%x\t&ptr: 0x%x\n", (int)dptr, (int)&ptr);
        printf("*dptr : 0x%x\tptr : 0x%x\n", (int)*dptr, (int)ptr);
        printf("**dptr: %d\t        *ptr: %d\n", **dptr, *ptr);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  dptr  : 0xbf8d6798 &ptr: 0xbf8d6798
  *dptr : 0xbf8d679c ptr : 0xbf8d679c
  **dptr: 10                 *ptr: 10



Below program illustrates how to perform dynamic memory allocation for double pointers.


  #include <stdio.h>
  #include <stdlib.h>
  int main() {
        int i, j, row, col, **mat1, **mat2, **res;

        /* input no of rows and columns from user */
        printf("Enter the number of rows and columns:");
        scanf("%d%d", &row, &col);

        /* dynamic memory allocation for double pointers */
        mat1 = (int **)malloc(sizeof(int) * row);
        mat2 = (int **)malloc(sizeof(int) * row);
        res  = (int **)malloc(sizeof(int) * row);

        for (i = 0; i < col; i++) {
                mat1[i] = (int *)malloc(sizeof(int) * col);
                mat2[i] = (int *)malloc(sizeof(int) * col);
                res[i] = (int *)malloc(sizeof(int) * col);
        }

        /* get the input for first matrix */
        printf("Enter your inputs for matrix1:\n");
        for (i = 0; i < row; i++) {
                for (j = 0; j < col; j++) {
                        scanf("%d", (*(mat1 +i) + j));
                }
        }

        /* get the input for second matrix */
        printf("Enter your inputs for matrix2:\n");
        for (i = 0; i < row; i++) {
                for (j = 0; j < col; j++) {
                        scanf("%d", (*(mat2 + i) + j));
                }
        }

        /* sum of given two matrices */
        for (i = 0; i < row; i++) {
                for (j = 0; j < col; j++) {
                        res[i][j] = mat1[i][j] + mat2[i][j];
                }
        }

        /* print the resultant matrix */
        printf("Result of addition of given two matrices:\n");
        for (i = 0; i < row; i++) {
                for (j = 0; j < col; j++) {
                        printf("%d ", res[i][j]);
                }
                printf("\n");
        }

        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Enter the number of rows and columns: 3   3
  Enter your inputs for matrix 1:
  10 10 10
  20 30 40
  10 20 30
  Enter your inputs for matrix 2:
  20 20 20
  30 30 30
  40 40 40

  Result of addition of given two matrices:
  30 30 30 
  50 60 70 
  50 60 70 


Pointer arithmetic - operations with pointers

Operations with pointers:
User can perform below operation with pointers:
  • Adding an integer to pointer
  • Subtracting an integer from pointer
  • Subtracting one pointer from another
  • Comparing two pointers
Adding an integer to pointer:
Consider ptr as a pointer to the array element arr[i], then ptr++ increments ptr to point to the array element arr[i + 1].  Similarly, if ptr points to the array element arr[i], and j is an integer, then "ptr = ptr + j" makes the pointer "ptr" to point to the array element arr[i + j].  


  #include <stdio.h>
  int main() {
        int *ptr, i = 0, arr[5] = {10, 20, 30, 40, 50};
        ptr = &arr[i];

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i, arr[i]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i, (int)&arr[i]);
        ++ptr, i++;

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i, arr[i]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i, (int)&arr[i]);
        ++ptr, i++;

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i, arr[i]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i, (int)&arr[i]);
        ptr = ptr + 2;

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i + 2, arr[i + 2]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i + 2, (int)&arr[i + 2]);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  *ptr: 10 arr[0]: 10 ptr: 0xbfcd1724 &arr[0]: 0xbfcd1724
  *ptr: 20 arr[1]: 20 ptr: 0xbfcd1728 &arr[1]: 0xbfcd1728
  *ptr: 30 arr[2]: 30 ptr: 0xbfcd172c &arr[2]: 0xbfcd172c
  *ptr: 50 arr[4]: 50 ptr: 0xbfcd1734 &arr[4]: 0xbfcd1734



Subtracting an integer from pointer:
Consider ptr as a pointer to the array element arr[i], then ptr-- decrements ptr to point to the array element arr[i - 1].  Similarly, if ptr points to the array element arr[i], and j is an integer, then ptr = ptr - j makes the pointer ptr to point to the array element arr[i -j].


  #include <stdio.h>
  int main() {
        int *ptr, i = 4, arr[5] = {10, 20, 30, 40, 50};
        ptr = &arr[i];

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i, arr[i]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i, (int)&arr[i]);
        --ptr, i--;

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i, arr[i]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i, (int)&arr[i]);
        --ptr, i--;

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i, arr[i]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i, (int)&arr[i]);
        ptr = ptr - 2;

        printf("*ptr: %d\tarr[%d]: %d\t", *ptr, i - 2, arr[i - 2]);
        printf("ptr: 0x%x\t&arr[%d]: 0x%x\n", (int)ptr, i - 2, (int)&arr[i - 2]);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  *ptr: 50 arr[4]: 50 ptr: 0xbf9ad2d4 &arr[4]: 0xbf9ad2d4
  *ptr: 40 arr[3]: 40 ptr: 0xbf9ad2d0 &arr[3]: 0xbf9ad2d0
  *ptr: 30 arr[2]: 30 ptr: 0xbf9ad2cc &arr[2]: 0xbf9ad2cc
  *ptr: 10 arr[0]: 10 ptr: 0xbf9ad2c4 &arr[0]: 0xbf9ad2c4



Subtracting one pointer from another:
Subtracting two pointers of same type ptr2 - ptr1 gives us the number of elements between the two pointers ptr1 and ptr2.  Below is an simple program that illustrates subtraction operation on pointers.


  #include <stdio.h>
  int main() {
        int num, *ptr1, *ptr2;
        int arr[5] = {10, 20, 30, 40, 50};

        /* assigning address to pointers */
        ptr1 = &arr[3];
        ptr2 = &arr[0];

        /* subtracting two pointers of same type */
        num = ptr1 - ptr2;

        printf("Number of elements between ptr1 and ptr2 is %d\n", num);
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ ./a.out
  Number of elements between ptr1 and ptr2 is 3



Comparing two pointers:
Comparison operations can also be performed on pointers.  Consider two pointers ptr1 and ptr2 points to members of same array, then 

  • If ptr1 is equal to ptr2, then both ptr1 and ptr2 points to same element in the given array.
  • If ptr1 is greater than ptr2, then ptr2 points to the earlier member in the given array.
  • If ptr1 is lesser than ptr2, then ptr1 points to the earlier member in the given array.

  #include <stdio.h>
  int main() {
        int *ptr1, *ptr2;
        int arr[5] = {10, 20, 30, 40, 50};

        /* assigning same address to pointer ptr1 and ptr2 */
        ptr1 = ptr2 = &arr[0];

        if (ptr1 == ptr2) {
                printf("Condition 1:\n");
                printf("ptr1 and ptr2 points to same element of the array\n");
                printf("ptr1: 0x%x\t*ptr1: %d\n", (int)ptr1, *ptr1);
                printf("ptr2: 0x%x\t*ptr2: %d\n", (int)ptr2, *ptr2);
        }

        /* advancing pointer ptr1 */
        ptr1 = ptr1 + 2;

        if (ptr1 > ptr2) {
                printf("\nCondition 2:\n");
                printf("ptr2 points to earlier element in the array\n");
                printf("ptr1: 0x%x\t*ptr1: %d\n", (int)ptr1, *ptr1);
                printf("ptr2: 0x%x\t*ptr2: %d\n", (int)ptr2, *ptr2);
        }

        /* advancing pointer ptr2 */
        ptr2 = ptr2 + 4;

        if (ptr2 > ptr1) {
                printf("\nCondition 3:\n");
                printf("ptr1 points to earlier element in the array\n");
                printf("ptr1: 0x%x\t*ptr1: %d\n", (int)ptr1, *ptr1);
                printf("ptr2: 0x%x\t*ptr2: %d\n", (int)ptr2, *ptr2);
        }

        return 0;
  }



  Output:
  Condition 1:
  ptr1 and ptr2 points to same element of the array
  ptr1: 0xbf83c374 *ptr1: 10
  ptr2: 0xbf83c374 *ptr2: 10

  Condition 2:
  ptr2 points to earlier element in the array
  ptr1: 0xbf83c37c *ptr1: 30
  ptr2: 0xbf83c374 *ptr2: 10

  Condition 3:
  ptr1 points to earlier element in the array
  ptr1: 0xbf83c37c *ptr1: 30
  ptr2: 0xbf83c384 *ptr2: 50



Can we add two pointers in C?
No, addition of two pointers is not allowed.


  #include <stdio.h>
  int main() {
        int *ptr1, *ptr2;
        int arr[5] = {10, 20, 30, 40, 50};

        /* adding two pointers */
        ptr1 = ptr1 + ptr2;
        return 0;
  }



  Output:
  jp@jp-VirtualBox:~/$ gcc addPtr.c 
  addPtr.c: In function ‘main’:
  addPtr.c:7: error: invalid operands to binary + (have ‘int *’ and ‘int *’)