gpt4 book ai didi

rust - Miri 在初始化和手动删除 MaybeUninit 时提示 UB

转载 作者:行者123 更新时间:2023-12-03 11:25:03 25 4
gpt4 key购买 nike

我正在编写代码来初始化 MaybeUninit 的数组s 并在出现 panic 时删除所有已初始化的元素。 Miri 提示未定义的行为,我已将其简化为以下示例。

use std::mem::{transmute, MaybeUninit};

fn main() {
unsafe {
let mut item: MaybeUninit<String> = MaybeUninit::uninit();
let ptr = item.as_mut_ptr();
item = MaybeUninit::new(String::from("Hello"));
println!("{}", transmute::<_, &String>(&item));
ptr.drop_in_place();
}
}

cargo miri run 产生的错误信息:

error: Undefined Behavior: trying to reborrow for SharedReadWrite at alloc1336, but parent tag <untagged> does not have an appropriate item in the borrow stack
--> /home/antek/.local/opt/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:179:1
|
179 | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trying to reborrow for SharedReadWrite at alloc1336, but parent tag <untagged> does not have an appropriate item in the borrow stack
|

据我所知,这正是 MaybeUninit 应该使用的方式。我是否错误地使用了界面并调用了未定义的行为,或者 Miri 是否过于保守?

最佳答案

您的问题实际上与 MaybeUninit 完全无关,可以归结为:

fn main() {
let mut item = 0;
let ptr = &item as *const _;
item = 1;
// or do anything with the pointer
unsafe { &*ptr; }
}

Playground link使用 Miri 运行时会抛出相同的“未定义行为”错误。 From what I could gather by reading their reference ,似乎 Miri 有一些元数据可以跟踪允许哪些指针读取项目,并且当您重新分配该项目时,元数据将被删除。然而,重新分配值不应该改变它们的内存地址,所以我会说这是 Miri 而不是 UB 的错误。

事实上,将 ptr 更改为 *mut i32 然后使用 ptr.write 而不是赋值实际上消除了 UB 警告,这意味着它可能是误报。

关于rust - Miri 在初始化和手动删除 MaybeUninit 时提示 UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66164453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com