From 7e04d7db029866eab0ff7c2a752edb2905bff61f Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Wed, 10 Apr 2013 13:58:20 +0200 Subject: [PATCH] Fix a serious bug in handmade_aligned_realloc: original data have to be moved if the alignment offset differs. --- Eigen/src/Core/util/Memory.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index 3d0994415..e1a160d2d 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -94,11 +94,11 @@ inline void throw_std_bad_alloc() /** \internal Like malloc, but the returned pointer is guaranteed to be 16-byte aligned. * Fast, but wastes 16 additional bytes of memory. Does not throw any exception. */ -inline void* handmade_aligned_malloc(size_t size) +inline void* handmade_aligned_malloc(std::size_t size) { void *original = std::malloc(size+16); if (original == 0) return 0; - void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(size_t(15))) + 16); + void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(15))) + 16); *(reinterpret_cast(aligned) - 1) = original; return aligned; } @@ -114,13 +114,18 @@ inline void handmade_aligned_free(void *ptr) * Since we know that our handmade version is based on std::realloc * we can use std::realloc to implement efficient reallocation. */ -inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0) +inline void* handmade_aligned_realloc(void* ptr, std::size_t size, std::size_t = 0) { if (ptr == 0) return handmade_aligned_malloc(size); void *original = *(reinterpret_cast(ptr) - 1); + std::ptrdiff_t previous_offset = static_cast(ptr)-static_cast(original); original = std::realloc(original,size+16); if (original == 0) return 0; - void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(size_t(15))) + 16); + void *aligned = reinterpret_cast((reinterpret_cast(original) & ~(std::size_t(15))) + 16); + void *previous_aligned = static_cast(original)+previous_offset; + if(aligned!=previous_aligned) + std::memmove(aligned, previous_aligned, size); + *(reinterpret_cast(aligned) - 1) = original; return aligned; } @@ -129,7 +134,7 @@ inline void* handmade_aligned_realloc(void* ptr, size_t size, size_t = 0) *** Implementation of generic aligned realloc (when no realloc can be used)*** *****************************************************************************/ -void* aligned_malloc(size_t size); +void* aligned_malloc(std::size_t size); void aligned_free(void *ptr); /** \internal