diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index ca9e9c41..9fa37108 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -217,6 +217,12 @@ static inline bool _mi_is_power_of_two(uintptr_t x) { return ((x & (x - 1)) == 0); } +// Is a pointer aligned? +static inline bool _mi_is_aligned(void* p, size_t alignment) { + mi_assert_internal(alignment != 0); + return (((uintptr_t)p % alignment) == 0); +} + // Align upwards static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) { mi_assert_internal(alignment != 0); diff --git a/src/alloc.c b/src/alloc.c index 30235944..19844849 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -633,7 +633,9 @@ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) memset((uint8_t*)newp + start, 0, newsize - start); } if mi_likely(p != NULL) { - _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + if mi_likely(_mi_is_aligned(p, sizeof(uintptr_t))) { // a client may pass in an arbitrary pointer `p`.. + _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + } mi_free(p); // only free the original pointer if successful } }