Rust 中是否明确定义了分配之间的比较指针?

发布于 2025-01-12 06:49:13 字数 515 浏览 0 评论 0原文

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

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

对于位于 buf 分配中的任何 ptr 是否保证 in_alloctrue,并且 false 在任何其他情况下?我们可以假设 ptr 是指向 T 对象的有效指针(因此不会未对齐/空/悬空),但是它可能来自也可能不是来自与 T 相同的分配代码>缓冲区。最后我们可以假设 T 的大小不为零。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

○愚か者の日 2025-01-19 06:49:13

回答标题,比较任何两个指针是明确定义的,因为指针实现 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);

例如,这经常用于 检查切片是否包含指针

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.

时光病人 2025-01-19 06:49:13

根据官方文档,在指针指向的对象的分配之后生成一个字节的原始指针是有效的(因此+1)。显然你不能取消引用指针,但它可以用于比较,例如。用于循环中的边界检查。

除此之外,它是未定义的行为,因此您根本无法保证任何事情。在您的情况下,由于这个原因,向指针添加任意偏移量并不是一个好主意。

因此,更具体地说,只要 buf.add(n) 指向的地址最多比对象 buf 的分配晚 1 个字节,它就会返回您期望的值 指向。

请参阅 https://doc.rust-lang .org/1.59.0/std/primitive.pointer.html#method.offset 了解更多详细信息。

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.

迷迭香的记忆 2025-01-19 06:49:13

是的,这段代码的工作原理与您所想的一样。比较指向不同分配的指针应按照 文档所暗示的方式进行操作std::ptr::eq 的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文