#define _BSD_SOURCE #include #include #include void *recallocarray(void *ptr, size_t om, size_t m, size_t n) { void *newptr; size_t old_size, new_size; if (n && m > -1 / n) { errno = ENOMEM; return 0; } new_size = m * n; if (n && om > -1 / n) { errno = EINVAL; return 0; } old_size = om * n; newptr = calloc(m, n); if (!newptr) return ptr; if (new_size <= old_size) { memcpy((char *) newptr, ptr, new_size); } else { memcpy((char *) newptr, ptr, old_size); memset((char *) newptr + old_size, 0, new_size - old_size); } memset(ptr, 0, old_size); free(ptr); return newptr; }