Reputation: 117771
I have a pointer buf: *const T
pointing to the start of an allocation of n
elements of T
, and I define the following check:
let in_alloc = buf <= ptr && ptr < unsafe { buf.add(n) };
Is it guaranteed that in_alloc
is true
for any ptr
that lies in the allocation of buf
, and false
in any other case? We may assume that ptr
is a valid pointer to a T
object (so not misaligned/null/dangling), however it may or may not be from the same allocation as buf
. Finally we may assume T
is not zero-sized.
Upvotes: 12
Views: 833
Reputation: 504083
Answering the title, comparing any two pointers is well-defined since pointers implement Ord
.
With pointers being totally ordered, the body of the question follows easily from this. You have a set of n
distinct pointers, starting at buf + 0
and ending at buf + (n - 1)
. If ptr
is less than buf
it can't be equal to any of them. If ptr
is greater than buf + (n - 1)
it also cannot be equal to them. If ptr
is one of them, both expressions evaluate to true.
You can somewhat sidestep the issue and use Range
instead:
let end = unsafe { buf.add(n) };
let in_alloc = (buf..end).contains(ptr);
This is often used, for example, to check if a slice contains a pointer.
Upvotes: 8
Reputation: 316
Yes, this code works as you would except. Comparing pointers that point to different allocations should behave as expected as implied by the documentation of std::ptr::eq.
Upvotes: 0
Reputation: 1052
According to the official documentation, it is valid to produce a raw pointer one byte past the allocation of the object the pointer points to (so +1). Obviously you cannot dereference the pointer, but it can be used for comparisons, eg. for bounds checking in a loop.
Beyond that, it's undefined behaviour, so you're not guaranteed anything at all. In your case adding an arbitrary offset to the pointer would not be a good idea for this reason.
So, to answer more specifically, it will return the value you expect as long as buf.add(n)
points to an address that is at most 1 byte past the allocation of the object buf
points to.
See https://doc.rust-lang.org/1.59.0/std/primitive.pointer.html#method.offset for more details.
Upvotes: 1