Pointers in C are used to store and manipulate the memory addresses of variables, enabling efficient memory access and dynamic memory management.
- C supports different pointer types, such as Null, Void, Wild, and Dangling pointers, each representing a specific pointer state or use case.
- Understanding these pointer types helps prevent common programming errors like invalid memory access, crashes, and memory leaks.
Dangling Pointer
A dangling pointer is a pointer that points to a memory location that has already been deallocated or deleted. Accessing such a pointer can lead to undefined behavior and program errors.
- It usually occurs after freeing dynamically allocated memory or when a local variable goes out of scope.
- Using a dangling pointer may cause unexpected behavior, crashes, or bugs in the program.
There are three different ways where a pointer acts as a dangling pointer:
1. De-allocation of Memory
When a memory pointed by a pointer is deallocated the pointer becomes a dangling pointer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr = (int*)malloc(sizeof(int));
// After below free call, ptr becomes a dangling pointer
free(ptr);
printf("Memory freed\n");
// removing Dangling Pointer
ptr = NULL;
return 0;
}
Output
Memory freed
2. Function Call
When the local variable is not static and the function returns a pointer to that local variable. The pointer pointing to the local variable becomes dangling pointer.
#include <stdio.h>
int* fun()
{
// x is local variable and goes out of
// scope after an execution of fun() is
// over.
int x = 5;
return &x;
}
// Driver Code
int main()
{
int* p = fun();
fflush(stdin);
// p points to something which is not
// valid anymore
printf("%d", *p);
return 0;
}
Output
0
Explanation
- p becomes a dangling pointer because it points to the local variable x, which is destroyed after the function returns.
- Declaring x as static keeps it in memory throughout the program, making the returned pointer valid.
#include <stdio.h>
int* fun()
{
// x now has scope throughout the program
static int x = 5;
return &x;
}
int main()
{
int* p = fun();
fflush(stdin);
// Not a dangling pointer as it points
// to static variable.
printf("%d", *p);
}
Output
5
3. Variable Goes Out of Scope
When a variable goes out of scope the pointer pointing to that variable becomes a dangling pointer.
#include <stdio.h>
#include <stdlib.h>
// driver code
int main()
{
int* ptr;
// creating a block
{
int a = 10;
ptr = &a;
}
// ptr here becomes dangling pointer
printf("%d", *ptr);
return 0;
}
Output
2355224Void Pointer
Void pointer (void *) is a generic pointer that can store the address of any data type. Since it has no specific data type, it can point to any type of variable.
- A void pointer cannot be dereferenced directly and must be typecast to the appropriate pointer type before accessing the data.
- Pointer arithmetic cannot be performed on a void pointer because the size of the data type is unknown.
#include <stdlib.h>
int main()
{
int x = 4;
float y = 5.5;
// A void pointer
void* ptr;
ptr = &x;
// (int*)ptr - does type casting of void
// *((int*)ptr) dereferences the typecasted
// void pointer variable.
printf("Integer variable is = %d", *((int*)ptr));
// void pointer is now float
ptr = &y;
printf("\nFloat variable is = %f", *((float*)ptr));
return 0;
}
Output
Integer variable is = 4 Float variable is = 5.500000
Syntax
void *ptrName;To know more refer to the void pointer article
NULL Pointer
NULL Pointer is a pointer that does not point to any valid memory location or object. It is used to indicate that the pointer is currently not assigned a valid address.
- NULL represents the absence of a valid memory address and is commonly used to initialize pointers safely.
- A NULL pointer should be checked before dereferencing to avoid undefined behavior or program crashes.
// C program to show the value of NULL pointer on printing
#include <stdio.h>
int main()
{
// Null Pointer
int* ptr = NULL;
printf("The value of ptr is %p", ptr);
return 0;
}
Output
The value of ptr is (nil)
Syntax
datatype *ptrName = NULL;Note NULL vs Uninitialized pointer - An uninitialized pointer stores an undefined value. A null pointer stores a defined value, but one that is defined by the environment to not be a valid address for any member or object.
NULL vs Void Pointer - Null pointer is a value, while void pointer is a type
Wild pointer
A wild pointer is a pointer that has been declared but not initialized. Since it contains a random (garbage) memory address, using it can lead to undefined behavior.
- A wild pointer does not point to a valid memory location and may cause crashes or memory access errors.
- It can be avoided by initializing pointers to NULL or assigning them a valid memory address before use.
#include <stdio.h>
int main()
{
int *ptr; // Wild pointer (uninitialized)
printf("The pointer is declared but not initialized.\n");
// Assign a valid memory address
int num = 10;
ptr = #
printf("Value of num: %d\n", *ptr);
return 0;
}
Syntax
dataType *pointerName;