我有一个指向T
的n
元素分配开始的指针buf: *const T
,我定义了以下检查:
let in_alloc = buf <= ptr && ptr < unsafe { buf.add(n) };
是否保证对于位于buf
的分配中的任何ptr
,in_alloc
是true
,以及在任何其他情况下,false
?我们可以假设ptr
是指向T
对象的有效指针(因此不会错位/空/悬空(,但它可能与buf
来自相同的分配,也可能不是。最后,我们可以假设T
不是零大小的。
回答标题,比较任何两个指针是定义良好的,因为指针实现了Ord
。
由于指针是完全有序的,因此问题的正文很容易从中得出。您有一组n
不同的指针,从buf + 0
开始,到buf + (n - 1)
结束。如果ptr
小于buf
,则它不可能等于它们中的任何一个。如果ptr
大于buf + (n - 1)
,则它也不能等于它们。如果ptr
是其中之一,则两个表达式的计算结果都为true。
您可以稍微回避这个问题,转而使用Range
:
let end = unsafe { buf.add(n) };
let in_alloc = (buf..end).contains(ptr);
例如,这通常用于检查切片是否包含指针。
根据官方文档,在指针指向(so+1(的对象的分配后一个字节生成原始指针是有效的。显然,您不能取消引用指针,但它可以用于比较,例如用于循环中的边界检查。
除此之外,这是一种未定义的行为,所以你根本不能得到任何保证。在您的情况下,由于这个原因,向指针添加任意偏移量不是一个好主意。
因此,更具体地说,只要buf.add(n)
指向的地址超过buf
指向的对象的分配最多1个字节,它就会返回您期望的值。
请参阅https://doc.rust-lang.org/1.59.0/std/primitive.pointer.html#method.offset了解更多详细信息。
是的,除了。比较指向不同分配的指针应该按照std::ptr::eq文档所暗示的那样进行操作。