Rust中是否定义了跨分配比较指针



我有一个指向Tn元素分配开始的指针buf: *const T,我定义了以下检查:

let in_alloc = buf <= ptr && ptr < unsafe { buf.add(n) };

是否保证对于位于buf的分配中的任何ptrin_alloctrue,以及在任何其他情况下,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文档所暗示的那样进行操作。

最新更新