Detailed articles like this are great for understanding and exposing all the freedom and power you get with C's memory management philosophy. I agree with the author's view that it is sufficiently complex that it can force you to think about not allocating, i.e. "should I really be doing this?" and thus you often arrive at a simpler, more efficient solution than you would if you'd used something like Java and thought "I'll just create a new X object". I see this all the time in C code written by programmers who first learnt Java - malloc()'ing and copying objects everywhere, often with an underuse of free() and thus plenty of memory leaks.
My personal preference is for not using fixed-length buffers for storing things like (non-static) strings, unless I know for certain that they won't ever grow past a certain length (and document it clearly, so if something ever needs a length check I can go back and find them); strings of user input and other possibly indeterminately long things get documented as "limited by available memory" (i.e. they're dynamically allocated) or "limited to X bytes" (usually due to a fixed-length buffer somewhere).
2) the writer may be using a different malloc than the libc one
3) there is an argument to be made that using malloc plainly like this instead of hiding it with strdup makes it easy to see the sites in your program where heap memory is allocated
My personal preference is for not using fixed-length buffers for storing things like (non-static) strings, unless I know for certain that they won't ever grow past a certain length (and document it clearly, so if something ever needs a length check I can go back and find them); strings of user input and other possibly indeterminately long things get documented as "limited by available memory" (i.e. they're dynamically allocated) or "limited to X bytes" (usually due to a fixed-length buffer somewhere).
As a note, the fragment
could be replaced by a single