Search code examples
c++pointersiterationmemory-address

Is there a way to check if a memory address is between two other addresses?


Let's say that, "hypothetically", I had this code:

//two separate arrays of the same object that for the purposes of this question we will assume are not adjacent in memory
ObjectName* m_objects0 = new ObjectName[10];
ObjectName* m_objects1 = new ObjectName[10];

//and a pointer to a single object
ObjectName* m_pObject = nullptr;

If I wanted to iterate over every object in m_objects0 until I reached the end, then "jump" to the start of m_objects1 to iterate over it, how would I check if the address of m_pObject sits between the start and end addresses of either array? (my only info being the start and end addresses of each array) Is it even feasible?

The only way I can think of accomplishing it is to somehow convert an address to an int.


Solution

  • You can check if a given pointer is (in)equal to any other pointer using the == and != operators.

    However, you can check if a given pointer is <(=) or >(=) another pointer only when both pointers are pointing within the same object/array, otherwise the behavior is undefined.

    So, while m_pObject is pointing at an element in m_objects0, you can't check if it is (not) pointing at an element in m_objects1 using address ranges.

    However, you can do something like this instead:

    ObjectName* m_objects0 = new ObjectName[10];
    ObjectName* m_objects1 = new ObjectName[10];
    
    ...
    
    ObjectName* object_ptrs[] = {
        m_objects0, m_objects0 + 10,
        m_objects1, m_objects1 + 10
    };
    
    for(int i = 0; i < 4; i += 2)
    {
        ObjectName* m_pObject = object_ptrs[i];
        ObjectName* m_pObjects_end = object_ptrs[i+1];
    
        while (m_pObject != m_pObjects_end)
        {
            ...
            ++m_pObject;
        }
    }
    
    ...
    

    Online Demo

    Which, you could generalize a bit further (ie, if you needed more than 2 arrays) using something this instead:

    #include <vector>
    #include <utility>
    
    ObjectName* m_objects0 = new ObjectName[10];
    ObjectName* m_objects1 = new ObjectName[10];
    ...
    
    std::vector<std::pair<ObjectName*,ObjectName*>> object_ptrs;
    object_ptrs.emplace_back(m_objects0, m_objects0 + 10);
    object_ptrs.emplace_back(m_objects1, m_objects1 + 10);
    ...
    
    for(auto &p : object_ptrs)
    {
        ObjectName* m_pObject = p.first;
        ObjectName* m_pObjects_end = p.second;
    
        while (m_pObject != m_pObjects_end)
        {
            ...
            ++m_pObject;
        }
    }
    
    ...
    

    Online Demo