A strong answer
Because C does not have templates or generics, it uses void * as its universal generic object pointer. Any object pointer (int *, struct node *, char *) converts to void * and back again implicitly without a cast in C. That allows functions like malloc(size_t size), memcpy(void *dst, const void *src, size_t n), and qsort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *)) to operate on memory buffers of any type.
However, because void is an incomplete type with no known size or layout, the compiler forbids two operations directly on a void *:
- You cannot dereference
*vp(the CPU would not know how many bytes to read). - You cannot perform pointer arithmetic
vp + 1in standard C (the compiler does not know the element stride).
To see how qsort sorts an arbitrary array through void *base, notice that the caller passes both nmemb (element count) and size (sizeof(element)). Internally, qsort casts base to unsigned char * (1-byte stride), computes the address of element i as (unsigned char *)base + i * size, and passes those element pointers as const void * to your comparison callback, which casts them back to const int * (or your struct type) before dereferencing.
What the interviewer is listening for
- Explains that
void *holds a raw memory address without type width, requiring explicit conversion to a concrete type before dereferencing andunsigned char *+sizefor generic element indexing. - Knows that
NULLrepresents a pointer guaranteed not to point to any valid object, and dereferencingNULLtriggers a hardware page fault on page0x0. - Mentions that in C (unlike C++),
void *converts implicitly to any object pointer, so castingmallocis unnecessary.
Common mistakes
- Dereferencing a
void *without first assigning or casting it to a typed pointer. - Violating alignment requirements by casting an unaligned
void *(e.g.,0x1001) touint64_t *and dereferencing it. - Assuming
void *is guaranteed by the C standard to hold function pointers (POSIX requiresdlsymto work withvoid *, but strict ISO C allows function pointers on Harvard architectures to have a different width than object pointers).