diff --git a/include/boost/python/make_constructor.hpp b/include/boost/python/make_constructor.hpp index 3ec9ad5f8..3769970ca 100644 --- a/include/boost/python/make_constructor.hpp +++ b/include/boost/python/make_constructor.hpp @@ -61,7 +61,8 @@ namespace detail typedef objects::pointer_holder holder; typedef objects::instance instance_t; - void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder)); + void* memory = holder::allocate(this->m_self, offsetof(instance_t, storage), sizeof(holder), + boost::python::detail::alignment_of::value); try { #if defined(BOOST_NO_CXX11_SMART_PTR) (new (memory) holder(x))->install(this->m_self); diff --git a/src/object/class.cpp b/src/object/class.cpp index 1a198408a..8bb462cee 100644 --- a/src/object/class.cpp +++ b/src/object/class.cpp @@ -766,10 +766,9 @@ void* instance_holder::allocate(PyObject* self_, std::size_t holder_offset, std: throw std::bad_alloc(); const uintptr_t x = reinterpret_cast(base_storage) + sizeof(alignment_marker_t); - //this has problems for x -> max(void *) - //const size_t padding = alignment - ((x + sizeof(alignment_marker_t)) % alignment); - //only works for alignments with alignments of powers of 2, but no edge conditions - const uintptr_t padding = alignment == 1 ? 0 : ( alignment - (x & (alignment - 1)) ); + // Padding required to align the start of a data structure is: (alignment - (x % alignment)) % alignment + // Since the alignment is a power of two, the formula can be simplified with bitwise AND operator as follow: + const uintptr_t padding = (alignment - (x & (alignment - 1))) & (alignment - 1); const size_t aligned_offset = sizeof(alignment_marker_t) + padding; void* const aligned_storage = (char *)base_storage + aligned_offset; BOOST_ASSERT((char *) aligned_storage + holder_size <= (char *)base_storage + base_allocation);