Which, it's not remotely a stupid question: malloc gets passed a zero-length argument when it's used to allocate variable length data. That malloc(0) works and is handled by free() without crashing the program is a simplifying assumption, as is the assumption that free(NULL) won't corrupt the heap.
Any use of alloca() on the other hand seems risky. Similar arguments could be made about the semantics of jmp_bufs, which also get used to get a handle on the stack.
"the assumption that free(NULL) won't corrupt the heap."
That's not an assumption, that's how the free() function is defined to work by the language standard. It never ceases to astound me how many otherwise good C programmers think free(NULL) is an error.
as is the assumption that free(NULL) won't corrupt the heap.
When you refer to simplifying assumptions, are you talking about assumptions made by the programmer, or by the compiler and libc? For example, the POSIX manual page[0] for free( void* ptr ) says, "If ptr is a null pointer, no action shall occur." The malloc manpage says, "If size is 0, either a null pointer or a unique pointer that can successfully passed to free() shall be returned." That sounds more like a definition than an assumption to me. What am I missing?
[0] Obtained by installing manpages-posix-dev on Ubuntu and running man 3posix free.