void *
The type-erased pointer, C's answer to generic programming
In a nutshell
void * is a pointer with no type attached. You cannot dereference it directly, but you can cast it to any other pointer type and then read or write through that cast. Library functions that must work on “any data” use void * in their signatures: memcpy, memset, qsort, malloc. It is C’s minimal version of Java’s generics.
Why it matters
Every generic container pattern in C (stacks, queues, hash tables that can hold any element type) uses void * at its interface. Lab 9 asks you to write a generic container, which is impossible without understanding the void * idiom. Also, malloc returns void * (you cast it to whatever you wanted), so every dynamic allocation you have been doing has been using void * under the hood.
Key takeaways
void *has no size information. You cannot dovoid *p; p++;because the compiler does not know what to advance by.- Cast to use.
int *ip = (int *)vp; *ip = 42;is the canonical pattern. sizeofis how generic code moves through arrays. Pass an element size as a parameter:void copy(void *dst, const void *src, size_t n, size_t element_size);.memcpyandmemsetare the two primitives that operate on raw bytes throughvoid *. They are the building blocks of any generic container.mallocreturnsvoid *. The common idiomint *p = malloc(n * sizeof(int));relies on an implicit cast.
Lessons in this topic
| Lesson | What it covers |
|---|---|
| Void Pointers | Declaring void *, the cast-to-use idiom, passing element size, memcpy/memset |
Practice and deep dives
Practice this topic: browse the practice gallery.
What comes next
Function Pointers — pointers to code rather than data. Together with void *, they make generic algorithms possible: qsort takes a void * array plus a comparator function pointer.