A structured lesson workspace with readable content, hands-on examples, and a clean path to completion.
malloc returns void*. In C, void* converts implicitly to any object pointer type. No cast is needed. int *p = malloc(n * sizeof(int)); compiles cleanly. In C++, the cast is required because C++ does not allow implicit void* conversion. The debate in C is purely stylistic, but it has strong opinions on both sides and the wrong choice in the wrong codebase will get your pull request rejected.
If you forget #include <stdlib.h>, the compiler assumes malloc returns int (the C89 implicit declaration rule). Without a cast, assigning an int to a pointer triggers a warning. With a cast, (int *)malloc(...) silences the warning because you are explicitly converting. The missing include is a real bug: on 64-bit systems, the int return truncates the pointer, and you get a corrupted address. The no-cast style lets the compiler catch this. The cast style hides it.
#include <stdio.h>int main(void) {int *p = malloc(10 * sizeof(int));free(p);return 0;}
Two warnings. Loud and clear. Add the cast and both warnings vanish. The bug remains. The code compiles. On a 64-bit system, the truncated pointer causes a crash or corruption at runtime. The no-cast style is a diagnostic aid.
In pure C code, do not cast malloc. In code that must compile as both C and C++, cast it. In a codebase with an existing style, follow the existing style. The technical argument favors no-cast. The social argument favors consistency. Both are valid. What is not valid is casting in C and then wondering why your missing-include bugs are invisible.
This debate will not be settled. It has been going on since the 1980s. Pick a side, apply it consistently, and move on. The bugs that matter are the ones after the allocation: the missing NULL check, the missing free, the buffer overflow. Next: resizing a dynamically allocated string, a practical application of realloc.
Finish the lesson once you have worked through the material. This awards ★ 20 XP.