How to check and find next aligned 32 byte address?

Hi everyone, I had a little question about data alignment with a given address.
Assumed we have a address p and we don't know it is 32 bytes aligned or not.
How can we check if it is 32 bytes aligned, if yes, then return original p, if not the return the next address, which is behind p and 32 bytes aligned?

1
2
uint8_t* p;  // which is given and has a address p
check_or_find_next_32B_alignment(p);
Last edited on
In general, to round val up to the nearest multiple of X, you do (val+X-1) / X * X.

When X is a power of 2 you can simplify with (val+X-1) & ~X.

The bit manipulation requires an integer type. You can use intptr_t, which is guaranteed to be able to hold a pointer. Here's an example, using all the bad casting operations. :)

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>

using namespace std;

int
main()
{
    uint8_t *p = (uint8_t *)0x12345678L;

    intptr_t val = (intptr_t)p;
    cout << (void*)p << '\t' << (void*)((val+31) & ~ intptr_t(31));
    return 0;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <memory>
#include <cstdint>

int main()
{
    const std::size_t SZ = 256*9 ;
    char buffer[SZ] {} ;

    void* ptr = buffer + 3 ; // +3 to make it an odd address
    // bytes available in the buffer from p onwards
    std::size_t bytes_available = std::end(buffer) - static_cast<char*>(ptr) ;\

    // object we want to place in the buffer is an array of size 253 bytes 
    // (note: using an odd size of 253 for exposition)
    const std::size_t object_size = sizeof( std::uint8_t[253] ) ;

    for( int i = 0 ; i < 10 ; ++i )
    {
        // if we could get a pointer aligned to a 32 byte boundary
        if( std::align( 32, object_size, ptr, bytes_available ) )
        {
            [[maybe_unused]] std::uint8_t* pui8 = static_cast<std::uint8_t*>(ptr) ;
            
            // bytes available in the buffer after this object is placed
            bytes_available = std::end(buffer) - static_cast<char*>(ptr) - object_size ;

            std::cout << "address: " << ptr << "  array of size: " << object_size
                      << "  bytes left: " << bytes_available << '\n' ;

            // bump the pointer to the next available address (to point to the byte immediately after this object)
            ptr = static_cast<char*>(ptr) + object_size ;
        }

        else // std::align failed
        {
            std::cout << "no more space. buffer exhausted.\n" ;
            break ;
        }
    }
}

http://coliru.stacked-crooked.com/a/aea840bc103712b2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
uint16_t getAddr(uint16_t addr)
{
    uint16_t answer;
    const uint16_t ALIGN_32_MASK = 0x1f;
    if ((addr & ~ALIGN_32_MASK) == addr)
        answer = addr;
    else
    {
        answer = addr >> 5;
        answer++;
        answer = answer << 5;
    }
    return answer;
}
Topic archived. No new replies allowed.