Dan*_*ath 2 unsafe segmentation-fault rust
几天前,有一个关于OOP的问题想要使用downcast来解决这个问题.作为一个自我挑战,我试图解决使用std::mem::transmute和不安全块的问题,这产生了分段错误.
代码的违规部分是这样的:
unsafe {
let storage =
mem::transmute::<&mut Box<AnyStorable + 'static>, &mut Box<Insertable<C>>>(x);
println!("{:#?}", x);
storage.insert(component); // This segfaults
};
Run Code Online (Sandbox Code Playgroud)
运行时会产生段错误:
/root/entrypoint.sh:line 7:5分段错误超时--signal = KILL $ {timeout}"$ @"
但是,当我更换此行时:
let storage =
mem::transmute::<&mut Box<AnyStorable + 'static>, &mut Box<Insertable<C>>>(x);
Run Code Online (Sandbox Code Playgroud)
有:
let storage =
mem::transmute::<&mut Box<AnyStorable + 'static>, &mut Box<VecStorage<C>>>(x);
Run Code Online (Sandbox Code Playgroud)
有用.为什么第一行失败而第二行没有?
Box<SomeTrait>存储两个指针:一个指向对象,一个指向vtable.Box<SomeType>只存储一个指针:一个指向对象.
您可以在示例中使用以下代码查看大小:
println!("{}", mem::size_of::<Box<AnyStorable + 'static>>());
println!("{}", mem::size_of::<Box<Insertable<C>>>());
println!("{}", mem::size_of::<Box<VecStorage<C>>>());
Run Code Online (Sandbox Code Playgroud)
调用transmute改变Box意志的特征打破了vtable:不同特征的vtable不兼容.
呼吁transmute改变从引用Box<SomeTrait>到的参考Box<SomeType>(和类型恰好是正确的)恰好作品,因为它只会使用第一个指向对象的指针,忘记性状.
胖子指针(即带有vtable的数据指针)的内部表示被定义TraitObject,只能在夜间构建中访问.虽然不太可能表示可能会改变数据指针不再是第一个指针的方式,这会破坏第二个指针transmute.
文档TraitObject也值得一读.
(虽然transmute确保传递类型的大小相等,但您传递的是对类型的引用 - 它们总是只有一个指针大.它不会检查这些引用所指向的类型.)
| 归档时间: |
|
| 查看次数: |
94 次 |
| 最近记录: |