Dangling pointer in C
Written by
Dangling Pointer
A dangling pointer points to a non-existent memory location. This pointer points to a memory location that has been freed. Dangling pointers arise when an object is deleted or de-allocated without modifying the value of the pointer.
Since the value of the pointer is not modified, it still points to the memory location of the de-allocated memory.
There are three cases where dangling pointers arise:
- Variable is out of scope
- De-allocation of memory
- Function call
We shall look at all of these cases in detail.
Variable out of scope
The pointer becomes a dangling pointer when the variable it is pointing to goes out of scope.
Let us understand this by the code snippet below:
#include <stdlib.h>
void main()
{
int *ptr = NULL;
{
int num;
ptr = #
//ptr is not dangling in the inner block
}
//ptr is dangling in the outer block as num is out of scope in this block
}
- Pointer Variable ptr is pointing to int type variable num which is declared in the inner block.
- num goes out of scope in the outer block.
- The pointer ptr is still pointing to the same memory location in outer block. However, int type variable num is not available at that memory location anymore. Hence, ptr becomes a dangling pointer in the outer block.
The solution is to extend the scope of the variable that the pointer is pointing to.
The above code when modified will be:
#include <stdlib.h>
void main()
{
int *ptr = NULL;
int num;
{
ptr = #
}
//ptr is not dangling in the outer block as num is not out of scope in this block
}
De-allocation of memory
Let us understand this concept by looking at the code snippet below:
#include <stdlib.h>
void main()
{
int *ptr = malloc(Constant_Value);
.......
.......
.......
free(ptr); //ptr now becomes a dangling pointer as we have de-allocated memory
}
We have declared the int type pointer ptr in the first step. After execution of some statements, we have de-allocated memory which was allocated previously for the pointer. As soon as the memory is de-allocated for pointer ptr, it becomes a dangling pointer.
This dangling pointer can be resolved. After de-allocating memory, initialize pointer to NULL so that pointer then points to nothing. Assigning NULL value means pointer is not pointing to any memory location. Therefore, the pointer will not be a dangling pointer anymore.
We can modify the above code to resolve this dangling pointer issue:
#include <stdlib.h>
void main()
{
int *ptr = malloc(Constant_Value);
.......
.......
.......
free(ptr); //ptr now becomes a dangling pointer as we have de-allocated memory
ptr = NULL; //ptr is not dangling anymore as it is pointing to nothing
}
Function Call
Such a problem arises when a local variable is not declared as static in a function body. It causes the pointer pointing to that local variable to become dangling.
Let us understand this concept by looking at the code snippet below:
#include <stdio.h>
int *funcName()
{
int num = 5;
return#
}
int main()
{
int *ptr = funcName();
fflush(stdin);
// ptr points to something which is not valid anymore
printf("%d", *ptr);
return 0;
}
- num is a local variable. It goes out of scope after execution of funcName() is over.
- When we are dereferencing the pointer ptr in the main method, ptr is pointing to something which is not valid anymore.
- Attempts to read from the pointer may still return the correct value for a while after calling funcName(), but any functions called thereafter will overwrite the stack storage allocated for num with other values and the pointer would no longer work correctly.
- If a pointer to num must be returned, num must have scope beyond the function—it might be declared as static.
To solve the problem of dangling pointers in case of function calls, we simply need to declare the variable that the pointer points to as static i.e. only one copy of that variable will be available for all objects.
Let us see how we can modify the above code so that ptr is not a dangling pointer anymore.
#include <stdio.h>
int *funcName()
{
static int num = 5; //declaring num as static
return #
}
int main()
{
int *ptr = funcName();
fflush(stdin);
// ptr is not dangling anymore
printf("%d", *ptr);
return 0;
}