Master the fundamental concepts of c programming deep dive through this focused micro-challenge.
C has no templates, so generic containers lean on void*. The Linux kernel's list_head macros, glib's GList, and qsort's comparator callback all erase types this way. A void* holds any address but cannot be dereferenced until you cast it back, and pointer arithmetic on void* is illegal in standard C.
cLoading…
malloc(size), then memcpy(node->data, src, size) so the list owns a copycompare function like qsort does; caller supplies type knowledgefree each data payload, then each node shellThe tradeoff is explicit: one implementation serves int, float, and structs, but the compiler cannot catch a wrong cast at retrieval time.
For this exercise, you will build create_node, prepend, append, find, and free_list around void*. This task asks you to feel why Rust added generics and why C libraries document compare-function contracts so carefully.
Keep the relevant man page, ABI doc, or Rust reference chapter open while you work. When your output disagrees with the reference implementation on the same machine, the mismatch is usually an alignment rule, an off-by-one terminator, or a register slot you misread in GDB. Skim the official documentation for the tool or ABI named in the exercise; the prose changes, but register roles, syscall numbers, and ownership rules stay stable across releases.
Implement a generic linked list using void* to store any data type.
Requirements:
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
All starter code and reference implementations are available for your local setup.
View on Github