当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Rust pointer.offset_from用法及代码示例


本文简要介绍rust语言中 pointer.offset_from 的用法。

用法

pub unsafe fn offset_from(self, origin: *const T) -> isize

计算两个指针之间的距离。返回值以 T 为单位:以字节为单位的距离除以 mem::size_of::<T>()

此函数是 offset 的反函数。

安全性

如果违反以下任何条件,则结果为未定义行为:

  • 起始指针和其他指针都必须位于同一 allocated object 的边界内或超出末尾一个字节。

  • 两个指针都必须从指向同一个对象的指针派生。 (请参见下面的示例。)

  • 指针之间的距离(以字节为单位)必须是 T 大小的精确倍数。

  • 指针之间的距离,以字节为单位,不能溢出isize.

  • 范围内的距离不能依赖于“wrapping around” 地址空间。

Rust 类型永远不会大于 isize::MAX 并且 Rust 分配永远不会环绕地址空间,因此任何 Rust 类型 T 的某个值内的两个指针将始终满足最后两个条件。标准库通常还确保分配永远不会达到需要考虑偏移量的大小。例如,VecBox 确保它们分配的字节数永远不会超过 isize::MAX,因此 ptr_into_vec.offset_from(vec.as_ptr()) 始终满足最后两个条件。

大多数平台根本无法构建如此大的分配。例如,没有已知的 64 位平台可以为 263由于page-table 限制或拆分地址空间而导致的字节数。但是,一些 32 位和 16 位平台可能会成功处理超过isize::MAX字节与物理地址扩展之类的东西。因此,直接从分配器或内存映射文件获取内存可能太大而无法处理此函数。 (注意offsetadd也有类似的限制,因此也不能用于如此大的分配。)

Panics

如果 T 是零大小类型 (“ZST”),则此函数会发生混乱。

例子

基本用法:

let mut a = [0; 5];
let ptr1: *mut i32 = &mut a[1];
let ptr2: *mut i32 = &mut a[3];
unsafe {
    assert_eq!(ptr2.offset_from(ptr1), 2);
    assert_eq!(ptr1.offset_from(ptr2), -2);
    assert_eq!(ptr1.offset(2), ptr2);
    assert_eq!(ptr2.offset(-2), ptr1);
}

不正确用法:

let ptr1 = Box::into_raw(Box::new(0u8));
let ptr2 = Box::into_raw(Box::new(1u8));
let diff = (ptr2 as isize).wrapping_sub(ptr1 as isize);
// Make ptr2_other an "alias" of ptr2, but derived from ptr1.
let ptr2_other = (ptr1 as *mut u8).wrapping_offset(diff);
assert_eq!(ptr2 as usize, ptr2_other as usize);
// Since ptr2_other and ptr2 are derived from pointers to different objects,
// computing their offset is undefined behavior, even though
// they point to the same address!
unsafe {
    let zero = ptr2_other.offset_from(ptr2); // Undefined Behavior
}

相关用法


注:本文由纯净天空筛选整理自rust-lang.org大神的英文原创作品 pointer.offset_from。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。