Dangling Pointers in C:
The most common bugs related to pointers and memory management is dangling/wild pointers. Sometimes the programmer fails to initialize the pointer with a valid address, then this type of initialized pointer is known as a dangling pointer in C.
Dangling pointer occurs at the time of the object destruction when the object is deleted or de-allocated from memory without modifying the value of the pointer. In this case, the pointer is pointing to the memory, which is de-allocated. The dangling pointer can point to the memory, which contains either the program code or the code of the operating system. If we assign the value to this pointer, then it overwrites the value of the program code or operating system instructions; in such cases, the program will show the undesirable result or may even crash. If the memory is re-allocated to some other process, then we dereference the dangling pointer will cause the segmentation faults.
Let’s observe the following examples.
In the above figure, we can observe that the Pointer 3 is a dangling pointer. Pointer 1 and Pointer 2 are the pointers that point to the allocated objects, i.e., Object 1 and Object 2, respectively. Pointer 3 is a dangling pointer as it points to the de-allocated object.
Let’s understand the dangling pointer through some C programs.
Using free() function to de-allocate the memory.
int *ptr=(int *)malloc(sizeof(int));
In the above code, we have created two variables, i.e., *ptr and a where ‘ptr’ is a pointer and ‘a’ is a integer variable. The *ptr is a pointer variable which is created with the help of malloc() function. As we know that malloc() function returns void, so we use int * to convert void pointer into int pointer.
The statement int *ptr=(int *)malloc(sizeof(int)); will allocate the memory with 4 bytes shown in the below image:
The statement free(ptr) de-allocates the memory as shown in the below image with a cross sign, and ‘ptr’ pointer becomes dangling as it is pointing to the de-allocated memory.
If we assign the NULL value to the ‘ptr’, then ‘ptr’ will not point to the deleted memory. Therefore, we can say that ptr is not a dangling pointer, as shown in the below image:
Variable goes out of the scope
When the variable goes out of the scope then the pointer pointing to the variable becomes a dangling pointer.
char a = ?A?;
str = &a;
// a falls out of scope
// str is now a dangling pointer
In the above code, we did the following steps:
- First, we declare the pointer variable named ‘str’.
- In the inner scope, we declare a character variable. The str pointer contains the address of the variable ‘a’.
- When the control comes out of the inner scope, ‘a’ variable will no longer be available, so str points to the de-allocated memory. It means that the str pointer becomes the dangling pointer.
Now, we will see how the pointer becomes dangling when we call the function.
Let’s understand through an example.
In the above code, we did the following steps:
- First, we create the main() function in which we have declared ‘p’ pointer that contains the return value of the fun().
- When the fun() is called, then the control moves to the context of the int *fun(), the fun() returns the address of the ‘y’ variable.
- When control comes back to the context of the main() function, it means the variable ‘y’ is no longer available. Therefore, we can say that the ‘p’ pointer is a dangling pointer as it points to the de-allocated memory.
Let’s represent the working of the above code diagrammatically.
Let’s consider another example of a dangling pointer.
static int y=10;
The above code is similar to the previous one but the only difference is that the variable ‘y’ is static. We know that static variable stores in the global memory.
Now, we represent the working of the above code diagrammatically.
The above diagram shows the stack memory. First, the fun() function is called, then the control moves to the context of the int *fun(). As ‘y’ is a static variable, so it stores in the global memory; Its scope is available throughout the program. When the address value is returned, then the control comes back to the context of the main(). The pointer ‘p’ contains the address of ‘y’, i.e., 100. When we print the value of ‘*p’, then it prints the value of ‘y’, i.e., 10. Therefore, we can say that the pointer ‘p’ is not a dangling pointer as it contains the address of the variable which is stored in the global memory.
Avoiding Dangling Pointer Errors
The dangling pointer errors can be avoided by initializing the pointer to the NULL value. If we assign the NULL value to the pointer, then the pointer will not point to the de-allocated memory. Assigning NULL value to the pointer means that the pointer is not pointing to any memory location.