Let's assume the types have been corrected.
malloc((size_t)0) behavior is defined by the implementation; there are two choices: (a) always returns a null pointer; or (b) acts like malloc((size_t)1) which can allocate or fail, and if it allocates then the program shall not try to reference anything through the returned non-null pointer.
Now, memset itself is required (among other things) to be given as its first argument a valid pointer to a byte array. In particular, it shall not be a null pointer. Tracking through the conformance requirements, if the malloc call returns a null pointer then the behavior is undefined. Thus, you should not program like this.
The argument "0" is not automatically converted to the right type unless there is a prototype in scope. It isn't as important in this case because it is highly likely that the appropriate prototype has been #included, but it is a bigger deal if we're dealing with arguments for a variadic function. Anyway, it's good to be reminded what the declared types are.
Are you serious? Of course the question comes with the reasonable assumption that the proper declaration has been made especially since it’s a well known standard function. Additionally memset() is not a variadic function.
You said the types were corrected, you didn’t say you were reminding about the declaration types. The types were correct from the start.