我有一個Result<Vec<f64>, _>. 當我嘗試提取指向實際f64陣列的指標時,我觀察到該陣列dptr指向的是預期陣列的損壞版本(前 10 個位元組已更改)。
為什么會發生這種情況,我該如何避免?
use std::error::Error;
fn main() {
let res: Result<Vec<f64>, Box<dyn Error>> = Ok(vec![1., 2., 3., 4.]);
let dptr: *const f64 = match res {
Ok(v) => &v[0],
Err(_) => std::ptr::null(),
};
assert_eq!(unsafe { *dptr }, 1.0);
}
結果:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `0.0`,
right: `1.0`', src/main.rs:9:5
操場
uj5u.com熱心網友回復:
該程式的行為是未定義的,通過在 Miri 下運行它可以看到,這是一個 Rust 解釋器,有時可以檢測到未定義的行為。(您可以在 Playground 中通過單擊“工具”(右上角)->“Miri”來執行此操作):
error: Undefined Behavior: pointer to alloc1039 was dereferenced after this allocation got freed
--> src/main.rs:9:25
|
9 | assert_eq!(unsafe { *dptr }, 1.0);
| ^^^^^ pointer to alloc1039 was dereferenced after this allocation got freed
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
這里發生的是釋放后使用:該Ok(v) => &v[0],行從v(并因此res)移動資料,導致它被釋放。后來,用于其他變數的資料覆寫了現有資料(因為在它指向的記憶體被釋放后使用指標是未定義的行為)。
如果您嘗試在res沒有 的情況下以正常方式讀取資料unsafe,那么您將在此問題上遇到編譯時錯誤:
error[E0382]: use of partially moved value: `res`
--> src/main.rs:9:10
|
6 | Ok(v) => &v[0],
| - value partially moved here
...
9 | dbg!(res.unwrap()[0]);
| ^^^ value used here after partial move
|
= note: partial move occurs because value has type `Vec<f64>`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving `res.0`
|
6 | Ok(ref v) => &v[0],
|
(操場)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/392691.html
上一篇:我在C中的結構鏈表有問題
下一篇:從鏈表中的指標存盤字串
