Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a pointer points to a properly aligned memory location?

Given a void * to some storage, how to check whether it points to properly aligned storage without any implementation defined behavior?

Of course we have std::align, but is there a more effective way to do this?

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: I need to do this in a C++ standards-compatible fashion, without relying on any platform-specific (implementation defined) hacks.

PPS: I apologize for my (comprehension of) English, its not my native language.


EDIT (2018.08.24): Removed "effective" from the title, added even more wording to emphasize that I don't want any implementation defined or platform-specific behavior.

like image 839
jotik Avatar asked Feb 07 '17 15:02

jotik


People also ask

How do I know if my address is 16 byte aligned?

If the address is 16 byte aligned, these must be zero. Notice the lower 4 bits are always 0. The cryptic if statement now becomes very clear and intuitive. We simply mask the upper portion of the address, and check if the lower 4 bits are zero.

What is an aligned pointer?

Aligned Pointer means that pointer with adjacent memory location that can be accessed by a adding a constant and its multiples. for char a[5] = "12345"; here a is constant pointer if you and the size of char to it every time you can access the next chracter that is, a +sizeofchar will access 2.

What does 4 byte aligned mean?

For instance, in a 32-bit architecture, the data may be aligned if the data is stored in four consecutive bytes and the first byte lies on a 4-byte boundary. Data alignment is the aligning of elements according to their natural alignment.

What is the purpose of memory alignment?

The CPU can operate on an aligned word of memory atomically, meaning that no other instruction can interrupt that operation. This is critical to the correct operation of many lock-free data structures and other concurrency paradigms.


Video Answer


1 Answers

If the remainder isn't zero when dividing the address with the desired alignment, then the address isn't aligned.

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

Ths can't be constexpr though, because of the cast.

Also, this relies on the implementation-defined fact that the conversion from pointer to integer must preserve the numeric representation of the address. As pointed out by the comments, that is not guaranteed by the standard, so this function is not necessarily portable to all platforms. That is also true, because it is optional for the implementation to provide std::uintptr_t.


I would expect this to only be needed when aligning for a type, so this might be more convenient:

template<class T> bool is_aligned(const void * ptr) noexcept {     auto iptr = reinterpret_cast<std::uintptr_t>(ptr);     return !(iptr % alignof(T)); } 
like image 185
eerorika Avatar answered Sep 28 '22 16:09

eerorika