A void
pointer is a pointer that has no associated data type with it. A void
pointer can hold address of any type and can be typcasted to any type. A void
pointer means a generic pointer that can point to any data type. We can assign the address of any data type to the void pointer, and a void
pointer can be assigned to any type of the pointer without performing any explicit typecasting.
void *pointer name;
Declaration of the void pointer
void *ptr;
In the above declaration, the void
is the type of the pointer, and 'ptr' is the name of the pointer.
Let us consider some examples.
int i=9; // integer variable initialization. int *p; // integer pointer declaration. float *fp; // floating pointer declaration. void *ptr; // void pointer declaration. p=fp; // incorrect. fp=&i; // incorrect ptr=p; // correct ptr=fp; // correct ptr=&i; // correct
In C the size of the void pointer in C is the same as the size of the pointer of character type.
Let's look at the below example:
#include <stdio.h> int main() { void *ptr = NULL; //void pointer int *p = NULL;// integer pointer char *cp = NULL;//character pointer float *fp = NULL;//float pointer //size of void pointer printf("size of void pointer = %d\n\n",sizeof(ptr)); //size of integer pointer printf("size of integer pointer = %d\n\n",sizeof(p)); //size of character pointer printf("size of character pointer = %d\n\n",sizeof(cp)); //size of float pointer printf("size of float pointer = %d\n\n",sizeof(fp)); return 0; }
Below are the advantages of a void pointer.
1) The malloc()
and calloc()
function return the void pointer, so these functions can be used to allocate the memory of any data type.
#include <stdio.h> #include<malloc.h> int main() { int a=90; int *x = (int*)malloc(sizeof(int)) ; x=&a; printf("Value which is pointed by x pointer : %d",*x); return 0; }
2) The void pointer in C can also be used to implement the generic functions in C.
The void pointer in C cannot be dereferenced directly using indirection (*) operator. Before you dereference a void pointer it must be typecasted to appropriate pointer type.
#include <stdio.h> int main() { int a=90; void *ptr; ptr=&a; printf("Value which is pointed by ptr pointer : %d",*ptr); return 0; }
In the above code, *ptr is a void pointer which is pointing to the integer variable 'a'. As we already know that the void pointer cannot be dereferenced, so the above code will give the compile-time error because we are printing the value of the variable pointed by the pointer 'ptr' directly.
Now, we rewrite the above code to remove the error.
#include <stdio.h> int main() { int a=90; void *ptr; ptr=&a; printf("Value which is pointed by ptr pointer : %d",*(int*)ptr); return 0; }
Typecast the above code to void pointer to the integer pointer by using the statement given below:
(int*)ptr;
Then, we print the value of the variable which is pointed by the void pointer 'ptr' by using the statement given below:
*(int*)ptr;
We can perform the arithmetic operations on the void pointers. Before you apply pointer arithmetic in void pointers we need to provide a proper typecast first otherwise you may get unexcepted results.
Let's see the below example:
#include<stdio.h> int main() { float a[4]={6.1,2.3,7.8,9.0}; void *ptr; ptr=a; for(int i=0;i<4;i++) { printf("%f,",*ptr); ptr=ptr+1; // Incorrect. }}
The above code shows the compile-time error that "invalid use of void expression" as we cannot apply the arithmetic operations on void pointer directly, i.e., ptr=ptr+1.
Let's rewrite the above code to remove the error.
#include<stdio.h> int main() { float a[4]={6.1,2.3,7.8,9.0}; void *ptr; ptr=a; for(int i=0;i<4;i++) { printf("%f,",*((float*)ptr+i)); }}
The above code runs successfully as we applied the proper casting to the void pointer, i.e., (float*)ptr and then we apply the arithmetic operation, i.e., *((float*)ptr+i).
Reusability is the main use of void pointers. Since void pointers can store the object of any type, we can retrieve the object of any type by using the indirection operator with proper typecasting.
Consider the below example.
#include<stdio.h> int main() { int a=56; // initialization of a integer variable 'a'. float b=4.5; // initialization of a float variable 'b'. char c='k'; // initialization of a char variable 'c'. void *ptr; // declaration of void pointer. // assigning the address of variable 'a'. ptr=&a; printf("value of 'a' is : %d",*((int*)ptr)); // assigning the address of variable 'b'. ptr=&b; printf("\nvalue of 'b' is : %f",*((float*)ptr)); // assigning the address of variable 'c'. ptr=&c; printf("\nvalue of 'c' is : %c",*((char*)ptr)); return 0; }