gpt4 book ai didi

segmentation-fault - 在实现两个段错误的类型上从特征 A 转换为特征 B

转载 作者:行者123 更新时间:2023-11-29 08:02:53 24 4
gpt4 key购买 nike

前几天有个OOP的题想用downcast解决。作为 self 挑战,我尝试使用 std::mem::transmute 解决问题。和不安全的 block ,这会产生段错误。

这是 full code in Rust Playground .

代码中有问题的部分是这样的:

unsafe {
let storage =
mem::transmute::<&mut Box<AnyStorable + 'static>, &mut Box<Insertable<C>>>(x);
println!("{:#?}", x);
storage.insert(component); // This segfaults
};

运行时产生段错误:

/root/entrypoint.sh: line 7: 5 Segmentation fault timeout --signal=KILL ${timeout} "$@"

但是,当我替换这一行时:

let storage =
mem::transmute::<&mut Box<AnyStorable + 'static>, &mut Box<Insertable<C>>>(x);

与:

let storage =
mem::transmute::<&mut Box<AnyStorable + 'static>, &mut Box<VecStorage<C>>>(x);

它有效。为什么第一行失败而第二行没有?

最佳答案

Box<SomeTrait>存储两个指针:一个指向对象,一个指向虚表。 Box<SomeType>仅存储一个指针:指向对象的指针。

您可以在示例中使用以下代码来查看尺寸:

println!("{}", mem::size_of::<Box<AnyStorable + 'static>>());
println!("{}", mem::size_of::<Box<Insertable<C>>>());
println!("{}", mem::size_of::<Box<VecStorage<C>>>());

调用 transmute改变 Box 的特征会破坏 vtable:不同 traits 的 vtable 不兼容。

调用 transmute从对 Box<SomeTrait> 的引用更改引用 Box<SomeType> (并且类型恰好是正确的类型)恰好有效,因为它只会使用指向对象的第一个指针而忘记特征。

胖指针(即带有 vtable 的数据指针)的内部表示在 TraitObject 中定义,只能在夜间构建中访问。虽然不太可能表示形式可能会改变,数据指针不再是第一个指针,这会破坏第二个 transmute .

TraitObject 的文档也值得一读。

(虽然 transmute 确保传递的类型的大小相等,但您传递的是对类型的引用——它总是恰好是一个指针大。它不检查这些引用指向的类型。)

关于segmentation-fault - 在实现两个段错误的类型上从特征 A 转换为特征 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48384622/

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