Before we move on with the course,
I want to demonstrate what we talked about in the previous lesson, and I
will do that by introducing the concept of void pointers.
So what is a void pointer? In a way, this is the purest kind of a pointer
because it doesn't have any specific data type attached to it.
This pointer literally only holds the memory address,
and there are no strings attached.
I created two pointers.
One of them is int, and the other one is void, but they both point
to the same place in memory, to the variable, x.
I will print out both of them so that we can verify this
claim. As you can see, both of the pointers store the same
memory address, which was expected.
But what will happen if we try to dereference them?
You can already see that my editor is warning me, but we'll compile
it anyway. And it seems like there's an error.
Void pointer is not a pointer‑to‑object type.
If you remember the previous lesson, this makes sense.
When we try to dereference this integer pointer,
the compiler will know that it should also look at the following three
bytes in memory because integer values are four bytes long.
But when we try to dereference a void pointer,
compiler will produce an error because there are no void variables.
If you want to dereference pointers,
the compiler needs to know which data type are they pointing to.
So, if we cannot dereference void pointers,
why would we ever use them? Void pointers can be used as a
placeholder or an interface for a piece of code that we want to
apply to multiple different types of pointers.
You will see an example of this in the last lesson of the module.
We have a memory address of this variable, x,
which means that we can simply cast this void pointer into an
integer pointer before dereferencing it.
And now, if I recompile the program,
you can see that everything works as expected.
Now you can see why data types in pointer declarations are
important. And now that we know all of this,
we can finally move on to dynamic memory allocation.