sirven que punteros puntero para operadores los lenguaje funciones estructura direccion datos con cadenas aritmetica apuntadores c++ c++11 c++14 memory-alignment c++17

c++ - que - punteros a cadenas



¿Cómo comprobar si un puntero apunta a una ubicación de memoria correctamente alineada? (1)

Dado un void * a algún almacenamiento, ¿cómo verificar si apunta a un almacenamiento correctamente alineado sin ningún comportamiento de implementación definido?

Por supuesto, tenemos std::align , pero ¿hay una forma más efectiva de hacerlo?

template <std::size_t alignment> inline bool is_aligned(void * ptr) noexcept { std::size_t max = 1u; return std::align(alignment, 1u, ptr, max); }

PS: Necesito hacer esto de una manera compatible con los estándares de C ++, sin depender de ningún hacks específico de la plataforma (definida por la implementación).

PPS: Me disculpo por mi (comprensión de) inglés, no es mi idioma nativo.

EDITAR (2018.08.24): Eliminado "efectivo" del título, agregando aún más palabras para enfatizar que no quiero ninguna implementación definida o comportamiento específico de la plataforma.


Si el resto no es cero al dividir la dirección con la alineación deseada, entonces la dirección no se alinea.

inline bool is_aligned(const void * ptr, std::uintptr_t alignment) noexcept { auto iptr = reinterpret_cast<std::uintptr_t>(ptr); return !(iptr % alignment); }

Sin embargo, esto no puede ser constexpr, debido al reparto.

Además, esto se basa en el hecho de la implementación definida, que la conversión de puntero a entero debe conservar la representación numérica de la dirección. Como lo indican los comentarios, eso no está garantizado por la norma, por lo que esta función no es necesariamente portátil para todas las plataformas. Eso también es cierto, porque es opcional para la implementación proporcionar std::uintptr_t .

Espero que esto solo sea necesario cuando se alinea para un tipo, por lo que podría ser más conveniente:

template<class T> bool is_aligned(const void * ptr) noexcept { auto iptr = reinterpret_cast<std::uintptr_t>(ptr); return !(iptr % alignof(T)); }