void *

Sometimes we know we want a pointer, but we don't necessarily know or care what it points to. The C/C++ language provides a special pointer, the void pointer, that allows us to create a pointer that is not type specific, meaning that it can be forced to point to anything.

Why is this useful? One common application of void pointers is creating functions which take any kind of pointer as an argument and perform some operation on the data which doesn't depend on the data contained. A function to "zero-out" memory (meaning to turn off all of the bits in the memory, setting each byte to the value 0) is a perfect example of this.

void memzero(void *ptr, size_t len) { for(; len>0; len--) { *(char *)ptr = 0; } }
This function takes a pointer to any piece of memory, meaning that we can pass in any kind of pointer we want, and the number of bytes to zero out. It then walks along the memory zeroing out each byte. Without void pointers, it would be more difficult to write a generic function like this.


You're probably wondering what that (char *) thing is in the memzero() function above. Well, it's what's called a cast. Casting is a way for a programmer to tell the computer that, even though the computer thinks something is one type, we want to treat it as another type.

You've probably already seen casting before, though not necessarily in the context of pointers. For example:

char steve; int spark; spark = 80; steve = spark;
In the above code, we're storing the number 80 into spark, and then storing the contents of the spark variable into steve. But spark is an integer and steve is a character. So, the computer has to cast the integer value 80 to the character value 80. This is referred to as an implicit cast, meaning that the computer knows what you want it to do, and automatically casts the value from an integer to a character for you.

The syntax used in the memzero() function above is referred to as an explicit cast, meaning that the programmer tells the computer exactly how the data should be treated. To convey to the computer that I wanted the pointer to be a treated as a character pointer, we put the type inside parentheses, as in (char *), and place it immediately before the item we want to cast, in this case, ptr. Once we perform this cast we can dereference the variable and set the memory's value to 0.

Why did I have to cast it? Why couldn't I have just done *ptr = 0? Because that statement doesn't make any sense to the computer. As far as the computer is concerned, ptr is just an address in memory; it has no type information associated with it. How does the computer know how many bytes this pointer points to? It doesn't. So telling the computer to set *ptr to 0 doesn't make any sense to it; in fact, a compiler shouldn't even be able to compile this since it's ambiguous. As such, we need to tell the computer exactly how we want to treat ptr. In this case, as we want to zero out each byte, we want to cast it to a data type that is exactly one byte long. A character is one byte long, so we cast the void *ptr to be a char *.