It depends on what you mean by UB.
Specifically, for pointer comparisons, section 5.9 "Relational Operators" of the C++ standard says:
If two pointers p and q of the same type point to different objects that are
not members of the same object or to different functions or if only one of
them is null, the results of p<q
, p>q
, p<=q
and p>=q
are unspecified.
Note that the behaviour is unspecified (meaning that the result of the comparison could be true
or false
- in other words the result doesn't tell you anything useful - but the implementation isn't required to specify which) as opposed to undefined (meaning that the compiler or the resulting program could do anything at all).
However, so far I have only seen one family of implementations that didn't do the expected thing with code like Kirill's:
bool inside = (other_pointer >= array) && (other_pointer < array+size);
Those implementations are compilers intended for building MS-DOS real-mode programs, in which addresses have a paragraph and offset part. The addresses FF00:0010 and FF01:0000 point to the same memory location but if I recall correctly the compilers weren't guaranteed to behave in the expected way, except when compiling for some memory models (certainly the HUGE model but perhaps others).
However, if either p
or q
does not point to an existing object (because for example the pointer was freed) then the behaviour is going to be undefined no matter what you do. So you can't use this kind of method to figure out if a pointer is still valid.