Small review
inline
void *alx_mallocarray (ptrdiff_t nmemb, size_t size)
{
if (nmemb < 0)
goto ovf;
if ((size_t)nmemb > (SIZE_MAX / size))
goto ovf;
return malloc(size * (size_t)nmemb);
ovf:
errno = ENOMEM;
return NULL;
}
(SIZE_MAX / size) overflows on pathological size==0 - code lacks protection.
Code does not certainly set errno when malloc() returns NULL. Suggest doing so if other code uses errno = ENOMEM;
ENOMEM is not part of standard C.
Pedantic: (size_t)nmemb potentially truncates. Could use (uintmax_t)nmemb instead to quiet mixed type warnings.
malloc(0) returning a non-NULL or NULL is often an annoying issue. I avoid with explicit code:
if (size == 0) size = 1; //allocate 1
// or depending on upper code use.
if (size == 0) return NULL.