void single pointers
In this section, you are going to learn about
What is the use of void pointers ?
How to use void pointers ?
Topics in this section,
void *ptr;
Single
void
pointer CAN NOT be dereferenced
1#include <stdio.h>
2
3int main(void)
4{
5 int a = 5;
6
7 void *ptr;
8
9 ptr = (void *) &a;
10
11 printf("a = %d\n", *ptr);
12
13 return 0;
14}
In above code, Line 11 is NOT VALID
$ cc p1_void_sp.c
p1_void_sp.c: In function ;main:
p1_void_sp.c:11:21: warning: dereferencing "void *" pointer
11 | printf("a = %d\n", *ptr);
| ^~~~
p1_void_sp.c:11:21: error: invalid use of void expression
void
pointer MUST be typecasted to type of originial data before using
1#include <stdio.h>
2
3int main(void)
4{
5 int a = 5;
6
7 void *ptr;
8
9 ptr = (void *) &a;
10
11 printf("a = %d\n", * (int *) ptr);
12
13 return 0;
14}
Note Line 11 in above code snippet. This is the right method to typecase and derefer
This is easy ! Just know the type of pointer assigned to void pointer !
Look at below examples
void pointer can hold the address of a character
Step 1 : Define a char
char a = 5;
Step 2 : Define a void pointer
void *ptr;
Step 3 : Assign address of char to void pointer
ptr = (void *) &a;
Note that,
typeof(ptr)
is void *
typeof(&a)
is char *
Step 4 : Derefer void pointer to access char
printf("a = %d\n", * (char *) ptr);
See full program below
1#include <stdio.h>
2
3int main(void)
4{
5 char a = 5;
6
7 void *ptr;
8
9 ptr = (void *) &a;
10
11 printf("a = %d\n", * (char *) ptr);
12
13 return 0;
14}
Alternatively, you can use an extra pointer of type
char *
. See below
1#include <stdio.h>
2
3int main(void)
4{
5 char a = 5;
6
7 void *ptr;
8
9 ptr = (void *) &a;
10
11 char *iptr;
12
13 iptr = (char *) ptr;
14
15 printf("a = %d\n", *iptr);
16
17 return 0;
18}
void pointer can hold the address of an integer
Step 1 : Define an integer
int a = 5;
Step 2 : Define a void pointer
void *ptr;
Step 3 : Assign address of int to void pointer
ptr = (void *) &a;
Note that,
typeof(ptr)
is void *
typeof(&a)
is int *
Step 4 : Derefer void pointer to access int
printf("a = %d\n", * (int *) ptr);
See full program below
1#include <stdio.h>
2
3int main(void)
4{
5 int a = 5;
6
7 void *ptr;
8
9 ptr = (void *) &a;
10
11 printf("a = %d\n", * (int *) ptr);
12
13 return 0;
14}
Alternatively, you can use an extra pointer of type
int *
. See below
1#include <stdio.h>
2
3int main(void)
4{
5 int a = 5;
6
7 void *ptr;
8
9 ptr = (void *) &a;
10
11 int *iptr;
12
13 iptr = (int *) ptr;
14
15 printf("a = %d\n", *iptr);
16
17 return 0;
18}
void pointer can hold the address of a structure
Step 1 : Define a Structure
struct ABC {
int x;
int y;
};
struct ABC a = { .x = 10, .y = 20 };
Step 2 : Define a void pointer
void *ptr;
Step 3 : Assign address of int to void pointer
ptr = (void *) &a;
Note that,
typeof(ptr)
is void *
typeof(&a)
is struct ABC *
Step 4 : Derefer void pointer to access members
printf("a.x = %d\n", ((struct ABC *) ptr)->x );
printf("a.y = %d\n", ((struct ABC *) ptr)->y );
See full program below
1#include <stdio.h>
2
3struct ABC {
4 int x;
5 int y;
6};
7
8int main(void)
9{
10 struct ABC a = { .x = 10, .y = 20 };
11
12 void *ptr;
13
14 ptr = (void *) &a;
15
16 printf("a.x = %d\n", ((struct ABC *) ptr)->x );
17 printf("a.y = %d\n", ((struct ABC *) ptr)->y );
18
19 return 0;
20}
Alternatively, you can use an extra pointer of type
struct ABC *
. See below
1#include <stdio.h>
2
3struct ABC {
4 int x;
5 int y;
6};
7
8int main(void)
9{
10 struct ABC a = { .x = 10, .y = 20 };
11
12 void *ptr;
13
14 ptr = (void *) &a;
15
16 struct ABC *sptr;
17
18 sptr = (struct ABC *) ptr;
19
20 printf("a.x = %d\n", sptr->x );
21 printf("a.y = %d\n", sptr->y );
22
23 return 0;
24}
void pointer can hold the address of a character array
Step 1 : Define a single dimension array of characters
char a[7] = "Laptop";
Step 2 : Define a void pointer and assign address of array to it
void *ptr;
ptr = (void *) a;
Step 3 : Access and Print the String : Typecasting method
printf("a = %s\n", (char *)ptr);
Step 4 : Access and Print the String : Separate pointer method
char *cptr;
cptr = (char *) ptr;
printf("a = %s\n", cptr);
Step 5 : Access and Print individual characters : Typecasting method
for (int i = 0; i < 7; i++)
{
printf("%c", ((char *)ptr)[i] );
}
Step 6 : Access and Print individual characters : Separate pointer method
char *ch_ptr;
ch_ptr = (char *) ptr;
for (int i = 0; i < 7; i++)
{
printf("%c", ch_ptr[i] );
}
See full program below
1#include <stdio.h>
2
3int main(void)
4{
5 char a[7] = "Laptop";
6
7 void *ptr;
8
9 ptr = (void *) a;
10
11 // Method 1 : Print String : Use Typecasting
12 printf("a = %s\n", (char *)ptr);
13
14 // Method 2 : Print String : Use Seprate pointer
15 char *cptr;
16
17 cptr = (char *) ptr;
18
19 printf("a = %s\n", cptr);
20
21 // Method 1 : Print Character : Use Typecasting
22 for (int i = 0; i < 7; i++)
23 {
24 printf("%c", ((char *)ptr)[i] );
25 }
26
27 printf("\n");
28
29 // Method 2 : Print Character : Use Separate pointer
30 char *ch_ptr;
31
32 ch_ptr = (char *) ptr;
33
34 for (int i = 0; i < 7; i++)
35 {
36 printf("%c", ch_ptr[i] );
37 }
38
39 printf("\n");
40
41 return 0;
42}
void pointer can hold the address of an integer array
Step 1 : Define a single dimension array of integers
int a[7] = { 0, 1, 2, 3, 4, 5, 6 };
Step 2 : Define a void pointer and assign address of array to it
void *ptr;
ptr = (void *) a;
Step 3 : Access and Print individual integers : Typecasting method
for (int i = 0; i < 7; i++)
{
printf("%d ", ((int *)ptr)[i] );
}
Step 4 : Access and Print individual integers: Separate pointer method
int *i_ptr;
i_ptr = (int *) ptr;
for (int i = 0; i < 7; i++)
{
printf("%d ", i_ptr[i] );
}
See full program below
1#include <stdio.h>
2
3int main(void)
4{
5 int a[7] = { 0, 1, 2, 3, 4, 5, 6 };
6
7 void *ptr;
8
9 ptr = (void *) a;
10
11 // Method 1 : Print Integers : Typecasting method
12 for (int i = 0; i < 7; i++)
13 {
14 printf("%d ", ((int *)ptr)[i] );
15 }
16
17 printf("\n");
18
19 // Method 2 : Print Integers : Separate Pointer method
20 int *i_ptr;
21
22 i_ptr = (int *)ptr;
23
24 for (int i = 0; i < 7; i++)
25 {
26 printf("%d ", i_ptr[i] );
27 }
28
29 printf("\n");
30
31 return 0;
32}
Output is as below
0 1 2 3 4 5 6
0 1 2 3 4 5 6
void pointer can hold the address of a structure array
Step 1 : Define a single dimension array of structures
struct ABC {
int x;
int y;
};
struct ABC a[3] = {
{ .x = 1, .y = 2 },
{ .x = 10, .y = 20 },
{ .x = 100, .y = 200 }
};
Step 2 : Define a void pointer and assign address of array to it
void *ptr;
ptr = (void *) a;
Step 3 : Access and Print individual structures : Typecasting method
for (int i = 0; i < 3; i++)
{
printf("a[%d].x = %d\t", i, ((struct ABC *)ptr)[i].x );
printf("a[%d].y = %d ", i, ((struct ABC *)ptr)[i].y );
printf("\n");
}
Step 4 : Access and Print individual structures : Separate pointer method
struct ABC *s_ptr;
s_ptr = (struct ABC *) ptr;
for (int i = 0; i < 3; i++)
{
printf("a[%d].x = %d\t", i, s_ptr[i].x );
printf("a[%d].y = %d ", i, s_ptr[i].y );
printf("\n");
}
See full program below
1#include <stdio.h>
2
3struct ABC {
4 int x;
5 int y;
6};
7
8int main(void)
9{
10 struct ABC a[3] = {
11 { .x = 1, .y = 2 },
12 { .x = 10, .y = 20 },
13 { .x = 100, .y = 200 }
14 };
15
16 void *ptr;
17
18 ptr = (void *) a;
19
20 // Method 1 : Print Integers : Typecasting method
21 for (int i = 0; i < 3; i++)
22 {
23 printf("a[%d].x = %d\t", i, ((struct ABC *)ptr)[i].x );
24 printf("a[%d].y = %d ", i, ((struct ABC *)ptr)[i].y );
25 printf("\n");
26 }
27
28 printf("\n");
29
30 // Method 2 : Print Integers : Separate Pointer method
31 struct ABC *s_ptr;
32
33 s_ptr = (struct ABC *) ptr;
34
35 for (int i = 0; i < 3; i++)
36 {
37 printf("a[%d].x = %d\t", i, s_ptr[i].x );
38 printf("a[%d].y = %d ", i, s_ptr[i].y );
39 printf("\n");
40 }
41
42 printf("\n");
43
44 return 0;
45}
void pointer can be passed as an argument to a function (By Value)
Step 1 : Define an Integer
int a = 5;
Step 2 : Define a
void
pointer and assign address of integer
void *ptr;
ptr = (void *) &a;
Step 3 : Pass
ptr
as call by Value to functionfun
fun(ptr);
Step 4 : Define function
fun
. Note the prototype !
void fun(void *p)
{
}
Step 5 : Derefer and access integer inside function
fun
void fun(void *p)
{
int *iv;
iv = (int *) p;
printf("a = %d\n", *iv);
}
See full program below
1#include <stdio.h>
2
3void fun(void *p)
4{
5 int *iv;
6
7 iv = (int *) p;
8
9 printf("a = %d\n", *iv);
10}
11
12int main(void)
13{
14 int a = 5;
15
16 void *ptr;
17
18 ptr = (void *) &a;
19
20 fun(ptr);
21
22 return 0;
23}
void pointer can be passed as an argument to a function (By Reference)
Step 1 : Define an Integer
int a = 5;
Step 2 : Define a
void
pointer and assign address of integer
void *ptr;
ptr = (void *) &a;
Step 3 : Pass
ptr
as call by Reference to functionfun
fun(&ptr);
Step 4 : Define function
fun
. Note the prototype !
void fun(void **p)
{
}
Step 5 : Derefer and access integer inside function
fun
void fun(void **p)
{
int *iv;
iv = (int *) *p;
printf("a = %d\n", *iv);
}
See full program below
1#include <stdio.h>
2
3void fun(void **p)
4{
5 int *iv;
6
7 iv = (int *) *p;
8
9 printf("a = %d\n", *iv);
10}
11
12int main(void)
13{
14 int a = 5;
15
16 void *ptr;
17
18 ptr = (void *) &a;
19
20 fun(&ptr);
21
22 return 0;
23}
void pointer can be used as part of an expression
Step 1 : Define an Integer
int a = 10;
Step 2 : Define a void pointer
ptr
and assign address of integer to it
void *ptr;
ptr = (void *) &a;
Step 3 : Derefer void pointer
ptr
and use in an expression
sum = *(int *)ptr + b + c;
This is also same as
sum = a + b + c;
See full program below
1#include <stdio.h>
2
3int main(void)
4{
5 int a = 10;
6 int b = 20;
7 int c = 30;
8
9 int sum;
10
11 void *ptr;
12
13 ptr = (void *) &a;
14
15 sum = a + b + c;
16
17 printf("sum = %d\n", sum);
18
19 sum = *(int *)ptr + b + c;
20
21 printf("sum = %d\n", sum);
22
23 return 0;
24}
void pointer can point to heap allocated memory
Step 1 : Define a void pointer
ptr
void *ptr;
Step 2 : Allocate memory from heap and assign to
ptr
ptr = malloc(40);
Step 3 : Assign void pointer to an integer pointer
int *iptr;
iptr = (int *) ptr;
Step 4 : Write : Use
iptr
to write to Heap memory
for (int i = 0; i < 10; i++)
{
iptr[i] = ++count;
}
Step 5 : Read : Use
iptr
to read from Heap memory
for (int i = 0; i < 10; i++)
{
printf("%d\n", iptr[i]);
}
See full program below
1#include <stdio.h>
2#include <stdlib.h>
3
4int main(void)
5{
6 void *ptr;
7
8 ptr = malloc(40);
9
10 int *iptr;
11
12 iptr = (int *) ptr;
13
14 int count = 0;
15
16 for (int i = 0; i < 10; i++)
17 {
18 iptr[i] = ++count;
19 }
20
21 for (int i = 0; i < 10; i++)
22 {
23 printf("%d\n", iptr[i]);
24 }
25
26 free(ptr);
27
28 return 0;
29}
We can define an Array of void pointers
Step 1 : Define an array of void pointers
void *ptr[4];
Step 2 : Assign individual void pointers
int a = 10;
char b = 20;
struct ABC c = { .x = 30, .y = 40 };
struct ABC d = { .x = 50, .y = 60 };
ptr[0] = (void *) &a;
ptr[1] = (void *) &b;
ptr[2] = (void *) &c;
ptr[3] = (void *) &d.x;
Step 3 : Use the void pointers in an expression. Remember to Typecast and Derefer !
sum = *(int *)ptr[0] +
*(char *)ptr[1] +
((struct ABC *)ptr[2]) -> x +
((struct ABC *)ptr[2]) -> y +
*(int *)ptr[3];
This is same as
sum = a + b + c.x + c.y + d.x;
See full program below
1#include <stdio.h>
2
3struct ABC {
4 int x;
5 int y;
6};
7
8int main(void)
9{
10 int a = 10;
11 char b = 20;
12 struct ABC c = { .x = 30, .y = 40 };
13 struct ABC d = { .x = 50, .y = 60 };
14
15 void *ptr[4];
16
17 ptr[0] = (void *) &a;
18 ptr[1] = (void *) &b;
19 ptr[2] = (void *) &c;
20 ptr[3] = (void *) &d.x;
21
22 int sum;
23
24 sum = *(int *)ptr[0] +
25 *(char *)ptr[1] +
26 ((struct ABC *)ptr[2]) -> x +
27 ((struct ABC *)ptr[2]) -> y +
28 *(int *)ptr[3];
29
30 printf("sum = %d\n", sum);
31
32 return 0;
33}
Array of void pointers can be passed as an argument to a function (By Value)
Step 1 : Define an array of void pointers
void *ptr[4];
Step 2 : Assign individual void pointers
int a = 10;
char b = 20;
struct ABC c = { .x = 30, .y = 40 };
struct ABC d = { .x = 50, .y = 60 };
ptr[0] = (void *) &a;
ptr[1] = (void *) &b;
ptr[2] = (void *) &c;
ptr[3] = (void *) &d.x;
Step 3 : Pass array of void pointers by Value to function
fun
fun(ptr);
Step 4 : Define the function
fun
void fun(void *p[4])
{
}
Step 5 : Use the void pointers in an expression. Remember to Typecast and Derefer !
void fun(void *p[4])
{
int sum;
sum = *(int *)p[0] +
*(char *)p[1] +
((struct ABC *)p[2]) -> x +
((struct ABC *)p[2]) -> y +
*(int *)p[3];
printf("sum = %d\n", sum);
}
See full program below
1#include <stdio.h>
2
3struct ABC {
4 int x;
5 int y;
6};
7
8void fun(void *p[4])
9{
10 int sum;
11
12 sum = *(int *)p[0] +
13 *(char *)p[1] +
14 ((struct ABC *)p[2]) -> x +
15 ((struct ABC *)p[2]) -> y +
16 *(int *)p[3];
17
18 printf("sum = %d\n", sum);
19}
20
21int main(void)
22{
23 int a = 10;
24 char b = 20;
25 struct ABC c = { .x = 30, .y = 40 };
26 struct ABC d = { .x = 50, .y = 60 };
27
28 void *ptr[4];
29
30 ptr[0] = (void *) &a;
31 ptr[1] = (void *) &b;
32 ptr[2] = (void *) &c;
33 ptr[3] = (void *) &d.x;
34
35 fun(ptr);
36
37 return 0;
38}
Array of void pointers can be passed as an argument to a function (By Reference)
Step 1 : Define an array of void pointers
void *ptr[4];
Step 2 : Assign individual void pointers
int a = 10;
char b = 20;
struct ABC c = { .x = 30, .y = 40 };
struct ABC d = { .x = 50, .y = 60 };
ptr[0] = (void *) &a;
ptr[1] = (void *) &b;
ptr[2] = (void *) &c;
ptr[3] = (void *) &d.x;
Step 3 : Pass array of void pointers by Reference to function
fun
fun(&ptr);
Step 4 : Define the function
fun
void fun(void * (*p) [4])
{
}
Step 5 : Use the void pointers in an expression. Remember to Typecast and Derefer !
void fun(void * (*p) [4])
{
int sum;
sum = *(int *)(*p)[0] +
*(char *)(*p)[1] +
((struct ABC *)(*p)[2]) -> x +
((struct ABC *)(*p)[2]) -> y +
*(int *)(*p)[3];
printf("sum = %d\n", sum);
}
See full program below
1#include <stdio.h>
2
3struct ABC {
4 int x;
5 int y;
6};
7
8void fun(void * (*p) [4])
9{
10 int sum;
11
12 sum = *(int *)(*p)[0] +
13 *(char *)(*p)[1] +
14 ((struct ABC *)(*p)[2]) -> x +
15 ((struct ABC *)(*p)[2]) -> y +
16 *(int *)(*p)[3];
17
18 printf("sum = %d\n", sum);
19}
20
21int main(void)
22{
23 int a = 10;
24 char b = 20;
25 struct ABC c = { .x = 30, .y = 40 };
26 struct ABC d = { .x = 50, .y = 60 };
27
28 void *ptr[4];
29
30 ptr[0] = (void *) &a;
31 ptr[1] = (void *) &b;
32 ptr[2] = (void *) &c;
33 ptr[3] = (void *) &d.x;
34
35 fun(&ptr);
36
37 return 0;
38}
void pointers can be defined inside a structure
Step 1 : Define a structure
struct ABC
with a void pointer
struct ABC {
int a;
int b;
int c;
void *pqr_ptr;
};
Step 2 : Define a structure
struct PQR
struct PQR {
int p;
int q;
int r;
};
Step 3 : Define structue objects for
struct ABC
andstruct PQR
struct ABC abc = {.a = 10, .b = 20, .c = 30 };
struct PQR pqr = {.p = 100, .q = 200, .r = 300 };
Step 4 : Assign void pointer inside
struct ABC
with address ofstruct PQR
abc.pqr_ptr = (void *) &pqr;
Step 5 : Assign void pointer
ptr
with address ofstruct ABC
ptr = (void *) &abc;
Step 6 : Pass
ptr
by Value to functionfun
fun(ptr);
Step 7 : Define the function
fun
void fun(void *ptr)
{
}
Step 8 : Use void pointers inside function
fun
. Typecast and Derefer
void fun(void *ptr)
{
struct ABC *abc_p;
struct PQR *pqr_p;
int sum;
abc_p = (struct ABC *)ptr;
pqr_p = (struct PQR *)abc_p->pqr_ptr;
sum = abc_p->a + abc_p->b + abc_p->c ;
sum += pqr_p->p + pqr_p->q + pqr_p->r;
printf("sum = %d\n", sum);
}
See full program below
1#include <stdio.h>
2
3struct PQR {
4 int p;
5 int q;
6 int r;
7};
8
9struct ABC {
10 int a;
11 int b;
12 int c;
13 void *pqr_ptr;
14};
15
16void fun(void *ptr)
17{
18 struct ABC *abc_p;
19 struct PQR *pqr_p;
20 int sum;
21
22 abc_p = (struct ABC *)ptr;
23 pqr_p = (struct PQR *)abc_p->pqr_ptr;
24
25 sum = abc_p->a + abc_p->b + abc_p->c ;
26
27 sum += pqr_p->p + pqr_p->q + pqr_p->r;
28
29 printf("sum = %d\n", sum);
30}
31
32int main(void)
33{
34 struct ABC abc = {.a = 10, .b = 20, .c = 30 };
35
36 struct PQR pqr = {.p = 100, .q = 200, .r = 300 };
37
38 abc.pqr_ptr = (void *) &pqr;
39
40 void *ptr;
41
42 ptr = (void *) &abc;
43
44 fun(ptr);
45
46 return 0;
47}
Learnings |
|
---|---|
Single void pointer CAN NOT be dereferenced directly without explicit typecast |
|
Single void pointer CAN HOLD the address of a character |
|
Single void pointer CAN HOLD the address of an integer |
|
Single void pointer CAN HOLD the address of a structure |
|
Single void pointer CAN HOLD the address of a character array |
|
Single void pointer CAN HOLD the address of an integer array |
|
Single void pointer CAN HOLD the address of a structure array |
|
Single void pointer CAN BE passed by value to a function |
|
Single void pointer CAN BE passed by reference to a function |
|
Single void pointer CAN BE used in an expression with explicit typecasting |
|
Single void pointer CAN POINT to memory block in Heap |
|
Array of Single void pointers CAN BE defined which can hold addresses of heterogeneous types |
|
Array of Single void pointers CAN BE passed by value to a function |
|
Array of Single void pointers CAN BE passed by reference to a function |
|
Single void pointers CAN BE used as structure members |
Current Module
Previous Module
Next Module
Other Modules