我在Ruust中创建了一个双向图,父指针是Ruustborrow 规则的一个明显问题,所以我使用了原始指针,这些指针在理论上是安全的,因为父指针拥有子指针,不能放在子指针之前.我唯一的问题(在我的头脑中)是当图表移动时.如果图形移动,则所有父指针都应该是无效的,因为它们指向图形的旧位置.

但通过举例测试,我得到了不同的结果.不仅在旧指针仍然有效的地方,调试器还在"寄存器&>有效地址"中显示一个新条目,该条目将旧指针映射到新位置. 我的测试代码:

fn main() -> Result<()> {

    let m = test();
    println!("MT:{}, IT:{}, PTR_MT:{}", m.j, m.inner.i, unsafe {(*m.inner.parent).j});
    Ok(())
}


fn test() -> Box<MyType> {
    let mut mytype = MyType { inner: MyInnerType { parent: std::ptr::null_mut(), i: 5 }, j:69 };
    println!("MT:{}, IT:{}", mytype.j, mytype.inner.i);
    mytype.inner.parent = &mut mytype;

    Box::new(mytype)
} 


struct MyType {
    inner: MyInnerType,
    j:i32
}

struct MyInnerType {
    parent: *mut MyType,
    i:i32
}

此行为是否已定义,我可以依赖它来工作吗?

推荐答案

不,这不安全.它是不健全的,表现出不确定的行为."程序按预期工作"是一种可能的结果,但不是唯一的结果.

Box::new(mytype)mytype移动到堆分配中,这不是UB.然而,由于指针目标已经被移动,所以稍后的判断*m.inner.parent导致UB.

通常,您应该避免在Rust中使用原始指针,除非您是在它们之上实现一个安全的抽象,或者您正在使用FFI而无法在没有它们的情况下完成您所需要的事情.

Rust相关问答推荐

将内部类型作为参数的泛型 struct 上的方法

铁 rust 干线无法使用PowerShell获取环境变量

有没有办法避免在While循环中多次borrow `*分支`

默认特征实现中的生命周期问题

为昂贵的for循环制作筛子

为什么铁 rust S的默认排序功能比我对小数组的 Select 排序稍微慢一些?

如何在函数中返回自定义字符串引用?

如何在嵌套的泛型 struct 中调用泛型方法?

无法将 rust 蚀向量附加到另一个向量

根据填充系数以相对大小在给定空间中布局项目

如何执行数组文字的编译时串联?

Rust 中的内存管理

在描述棋盘时如何最好地使用特征与枚举

当锁被释放时,将锁包装到作用域中是否会发生变化?

没有明确地说return会产生错误:match arms have incompatible types

是否可以在 Rust 中的特定字符上实现特征?

为什么允许重新分配 String 而不是 *&String

如何在 Rust 中返回通用 struct

在单独的线程上运行 actix web 服务器

在 Traits 函数中设置生命周期的问题