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(non_zero) 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.