當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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 a = [0; 5];
let ptr1: *const i32 = &a[1];
let ptr2: *const i32 = &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)) as *const u8;
let ptr2 = Box::into_raw(Box::new(1u8)) as *const u8;
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 *const 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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。