+/**
+ * Reallocate an array, abort on failure or bugs.
+ *
+ * \param ptr Pointer to the memory block, may be NULL.
+ * \param nmemb Number of elements.
+ * \param size The size of one element in bytes.
+ *
+ * A wrapper for realloc(3) which aborts on invalid arguments or integer
+ * overflow. The wrapper also terminates the current process on allocation
+ * errors, so the caller does not need to check for failure.
+ *
+ * \return A pointer to newly allocated memory which is suitably aligned for
+ * any kind of variable and may be different from ptr.
+ *
+ * \sa realloc(3).
+ */
+__must_check void *arr_realloc(void *ptr, size_t nmemb, size_t size)
+{
+ size_t pr;
+
+ assert(size > 0);
+ assert(nmemb > 0);
+ assert(!__builtin_mul_overflow(nmemb, size, &pr));
+ assert(pr != 0);
+ ptr = realloc(ptr, pr);
+ assert(ptr);
+ return ptr;
+}
+
+/**
+ * Allocate an array, abort on failure or bugs.
+ *
+ * \param nmemb See \ref arr_realloc().
+ * \param size See \ref arr_realloc().
+ *
+ * Like \ref arr_realloc(), this aborts on invalid arguments, integer overflow
+ * and allocation errors.
+ *
+ * \return A pointer to newly allocated memory which is suitably aligned for
+ * any kind of variable.
+ *
+ * \sa See \ref arr_realloc().
+ */
+__must_check __malloc void *arr_alloc(size_t nmemb, size_t size)
+{
+ return arr_realloc(NULL, nmemb, size);
+}
+
+/**
+ * Allocate and initialize an array, abort on failure or bugs.
+ *
+ * \param nmemb See \ref arr_realloc().
+ * \param size See \ref arr_realloc().
+ *
+ * This calls \ref arr_alloc() and zeroes-out the array.
+ *
+ * \return See \ref arr_alloc().
+ */
+__must_check __malloc void *arr_zalloc(size_t nmemb, size_t size)
+{
+ void *ptr = arr_alloc(nmemb, size);
+
+ /*
+ * This multiplication can not overflow because the above call to \ref
+ * arr_alloc() aborts on overflow.
+ */
+ memset(ptr, 0, nmemb * size);
+ return ptr;
+}
+
+/**
+ * Allocate and initialize memory.
+ *
+ * \param size The desired new size.
+ *
+ * \return A pointer to the allocated and zeroed-out memory, which is suitably
+ * aligned for any kind of variable.
+ *
+ * \sa \ref alloc(), calloc(3).
+ */
+__must_check void *zalloc(size_t size)
+{
+ return arr_zalloc(1, size);
+}
+