Void Pointer

On different system, the size of the pointer can vary. Also on different data type that the pointer points to, the size can vary.

Therefore you can run into the trouble of assigning various type of other pointers to different type.

As a result, C provides a pointer of type (void*)

void *ptr

This can be use to point to any object of any data type.

For example

#include <stdio.h>

int main() {
    int array[] = {9,2,3,4};
    void *ptr = array;
    printf("ptr: %p,value ptr: %d\n", ptr, *((int*) ptr));
}

In here, to read the value of array (Pointer and Array) which is the first element of the array, we need to cast it to (int*) pointer and then dereference.

As a result, it will give us value 9.

ptr: 0x16dcbad90, value ptr: 9

Arithmetic

If we declare our pointer as void *, when doing Pointer Arithmetic, for example

#include <stdio.h>

int main() {
    int array[] = {4129,2,3,4};
    void *ptr = array;
    printf("ptr: %p, nextPtr: %p\n", ptr, ptr + 1);
}

Since the type of the pointer is undefine, it default to char pointer. Therefore, we only add 1 to the pointer. For example:

ptr: 0x16fdbad90, nextPtr: 0x16fdbad91

BONUS: What happen if you dereference this value?

Since 4129 in heximal would be

Address0123
Data21100000

0x16fdbad91 would try to dereference from 10 + next 4 bytes and lead to unexpected value.

#include <stdio.h>

int main() {
    int array[] = {4129,2,3,4};
    void *ptr = array;

    void *nPtr = ptr + 1;
    printf("ptr: %p, nPtr: %p, nextPtrValue: %d\n", ptr, nPtr, *((int*) nPtr));
}
ptr: 0x16f43ad90, nPtr: 0x16f43ad91, nextPtrValue: 33554448

As a result, we can see that it tries to make 33554448 which is in heximal:

Address0123
Data10000002

Which started at 10 and the next value will overlap 2 (the second element in the array) which has the heximal of 02 00 00 00

Explain

So in total, consider the first 2 values {4129, 2} we have the memory looking like this:

Address01234567
Data2110000002000000

Which:

  • the first 4 address (0x00001021) will be 4129
  • the next 4 address (0x00000002) will be 2
In [10]: int("00001021",16)
Out[10]: 4129

In [11]: int("00000002",16)
Out[11]: 2

Therefore, when (0x16f43ad91) — which start from address 1 trying to dereference as int, it will try to read the next 4 bytes from address 1.

Which is:

Address1234
Data10000002

Which is 0x02000010 in heximal. When converting it to int, we have

In [12]: int("02000010",16)
Out[12]: 33554448