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.

No comments:

Post a Comment