Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

checking if pointer points within an array

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

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

Or do the pointer comparisons invoke undefined behavior if p points outside the bounds of the array? In that case, how do I solve the problem? Does it work with void pointers? Or is it impossible to solve?

like image 226
fredoverflow Avatar asked Jan 11 '11 13:01

fredoverflow


2 Answers

Although the comparison is valid only for pointers within the array and "one past the end", it is valid to use a set or map with a pointer as the key, which uses std::less<T*>

There was a big discussion on this way back in 1996 on comp.std.c++

like image 58
CashCow Avatar answered Oct 18 '22 23:10

CashCow


Straight from the MSDN documentation:

Two pointers of different types cannot be compared unless:

  • One type is a class type derived from the other type.
  • At least one of the pointers is explicitly converted (cast) to type void *. (The other pointer is implicitly converted to type void * for the conversion.)

So a void* can be compared to anything else (including another void*). But will the comparison produce meaningful results?

If two pointers point to elements of the same array or to the element one beyond the end of the array, the pointer to the object with the higher subscript compares higher. Comparison of pointers is guaranteed valid only when the pointers refer to objects in the same array or to the location one past the end of the array.

Looks like not. If you don't already know that you are comparing items inside the array (or just past it), then the comparison is not guaranteed to be meaningful.

There is, however, a solution: The STL provides std::less<> and std::greater<>, which will work with any pointer type and will produce valid results in all cases:

if (std::less<T*>()(p, begin)) {
    // p is out of bounds
}

Update:

The answer to this question gives the same suggestion (std::less) and also quotes the standard.

like image 35
Jon Avatar answered Oct 19 '22 01:10

Jon