Array of all permutations in C
verbose vs readable

Why choose?

Just encapsulate all the explicit code and error checkings into functions (if possible) or macros (only when functions can't do it), and have a clean high level function.



Safe usage of malloc()

Malloc is easily misused.  Problems using malloc are the following:


sizeof(type) vs sizeof(*foo):


foo = malloc(sizeof(*foo) * nmemb); is better because if you ever change the type of foo, this call will still be valid, while if not, you would have to change every line where malloc is called with foo.  If you forget any of those lines, good luck!


overflow:


If (sizeof(*foo) * nmemb) &gt; SIZE_MAX, it will silently wrap around, and allocate a very small amount of memory, and you will most likely end up accessing memory that you shouldn't.

Solution:

Use this enclosure around malloc



sizeof(type) vs sizeof(*foo)

As I said above, use the second.  Apart from malloc you also have this problem in memcpy.



fprintf(stderr, ...) + exit()

You could combine those two in just one function call:

error(): GNU extension

err(): BSD extension

I would advise to use the first one: first, GNU extensions are more commonly available (even Clang has most (if not all) of them); second, because err is a common name used in temporary variables or labels used in case of an error.



C99 types

If you don't have a reason to use old C89 (yes, 1989) types, don't use them. What is long long, and why would you use it?

int64_t is clearer, shorter, and better in every way, unless you need to interface a library that hasn't been updated in the last 30 years, which ironically is most of them.

Also instead of int, use int32_t, although if you want factorials that fit into an int64_t, I don't think you need more than int8_t.