checking if pointer points within an array

后端 未结 6 2034
半阙折子戏
半阙折子戏 2020-12-06 01:25

Can I check whether or not a given pointer points to an object within an array, specified by its bounds?

template 
bool points_within_array         


        
6条回答
  •  甜味超标
    2020-12-06 01:52

    The only correct way to do this is an approach like this.

    template 
    bool points_within_array(T* p, T* begin, T* end)
    {
        for (; begin != end; ++begin)
        {
            if (p == begin)
                return true;
        }
        return false;
    }
    

    Fairly obviously, this doesn't work if T == void. I'm not sure whether two void* technically define a range or not. Certainly if you had Derived[n], it would be incorrect to say that (Base*)Derived, (Base*)(Derived + n) defined a valid range so I can't see it being valid to define a range with anything other than a pointer to the actual array element type.

    The method below fails because it is unspecified what < returns if the two operands don't point to members of the same object or elements of the same array. (5.9 [expr.rel] / 2)

    template 
    bool points_within_array(T* p, T* begin, T* end)
    {
        return !(p < begin) && (p < end);
    }
    

    The method below fails because it is also unspecified what std::less::operator() returns if the two operands don't point to members of the same object or elements of the same array.

    It is true that a std::less must be specialized for any pointer type to yield a total order if the built in < does not but this is only useful for uses such as providing a key for a set or map. It is not guaranteed that the total order won't interleave distinct arrays or objects together.

    For example, on a segmented memory architecture the object offset could be used for < and as the most significant differentiator for std::less with the segment index being used to break ties. In such a system an element of one array could be ordered between the bounds of a second distinct array.

    template 
    bool points_within_array(T* p, T* begin, T* end)
    {
        return !(std::less()(p, begin)) && (std::less()(p, end));
    }
    

提交回复
热议问题