Dangling pointer

Dangling pointers arise when the referencing object is deleted or deallocated, without changing the value of the pointers. It creates the problem because the pointer is still pointing to the memory that is not available. When the user tries to dereference the daggling pointers than it shows the undefined behavior and can be the cause of the segmentation fault. Dangling pointers are nasty bugs because they seldom crash the program until long after they have been created, which makes them hard to find. Programs that create dangling pointers often appear to work on small inputs, but are likely to fail on large or complex inputs.

// newFoo creates a dangling pointer by deleting the client's C-style string.
typedef char * Foo;

Foo newFoo (char * x) {
    Foo tmp = new char [strlen (x) +1] ;
    strcpy (tmp, x);
    delete [] x;
    return tmp;
}

 

Common cause that creates the dangling pointer.

  • When a variable goes out of the scope
    A local variable’s scope and lifetime belong to their block where it is declared. Whenever control comes to the block than memory is allocated to the local variable and freed automatically upon exit from the block. If a local variable is referred to outside of its lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when the variable it points to reaches the end of its lifetime.

    #include <stdio.h>
    int main(void)
    {
      int *piData;
       
      // Code block
      {
        int Data = 27;
        piData = &Data;
      }
       
      // piData is dangling pointer 
      printf("piData = %d\n", *piData);
       
      return 0;
    }
  • After destroying of stack frame
    The stack frame that is allocated to a function is destroyed after returning the control from the function. If you tried to access the returning address from the pointer, you will get the unpredictable result or might get the same value but it is very dangerous and need to avoid.

    int *Fun()
    {
      // Local variable
      int Data = 5;
       
      // Address of local variable 
      return &Data;
    }
     
     
    int main()
    {
      // Returning address of the local variable
      int *piData = Fun();
      
      // Dangling pointer that is pointing a memory which is not available.  
      printf("%d", *piData);
       
      return 0;
    }
  • Deleting the memory explicitly
    In C, compiler handles static and auto allocated memory but if the user allocates the memory manually than it is the responsibility of the user to free the manually allocated memory. Access to freed memory after the allocated memory will lead to dangling pointers.

    int main()
    {
      int *piData = NULL;
       
      // creating integer of size 10. 
      piData = malloc(sizeof(int)* 10);
       
      // free the allocated memory 
      free(piData);
       
      // piData is dangling pointer 
      *piData = 10;
       
      return 0;
    }

     

Wild pointer

A pointer that is not initialized properly prior to its first use is known as the wild pointer. Uninitialized pointers behavior is totally undefined because it may point some arbitrary location that can be the cause of the program crash, that’s is the reason it is called a wild pointer. In the other word, if a pointer is not initialized either by the compiler or programmer begins as a wild pointer.

// piData is wild pointer
int *piData;

 

Null pointer

Null Pointer is a pointer which is pointing to nothing. In case, if we don’t have address to be assigned to a pointer, then we can simply use NULL.

// piData is a null pointer.
int *piData = 0;

 

Void pointer

A void pointer is a generic pointer, it has no associated data type. It can store the address of any type of object and it can be type-casted to any types. According to C standard, the pointer to void shall have the same representation and alignment requirements as a pointer to a character type.A void pointer declaration is similar to the normal pointer, but the difference is that instead of data types we use the void keyword. Important Points

  • void pointers cannot be dereferenced. It can however be done using typecasting the void pointer
  • Pointer arithmetic is not possible on pointers of void due to lack of concrete value and thus size.
int main(int argc, char *argv[])
{
  void *pvData;

  int iData = 6;   
  pvData = &iData;   
  printf("pvData = %d",*(int*)pvData);
   
  return 0;
}