gpt4 book ai didi

rust - 原始指针的数据消失

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

考虑下面的代码:

struct Person {
mate: Option<*const Person>,
siblings: Vec<i32>,
}

impl Person {
fn meets(&mut self, mate: &mut Person) {
self.mate = Some(mate);
mate.mate = Some(self);
}
}

struct Bar {
person: Person,
}

impl Bar {
fn addr(&self) {
unsafe {
println!("\n`bob.siblings.len()`: {}, `bob.susan.siblings.len()`: {}",
self.person.siblings.len(), (*self.person.mate.unwrap()).siblings.len());

println!("\n but wait -> `bob.susan.bob.siblings.len()`: {} ??",
(*(*self.person.mate.unwrap()).mate.unwrap()).siblings.len());

println!("\nthis is `bob.susan.bob's address`: {:p} => same address inside bar ???",
(*self.person.mate.unwrap()).mate.unwrap());
}
}
}

fn main() {
let mut bob = Person {
mate: None,
siblings: {
let mut stuff: Vec<i32> = Vec::new();
unsafe {
stuff.set_len(2);
}
stuff
}
};

let mut susan = Person {
mate: None,
siblings: {
let mut stuff: Vec<i32> = Vec::new();
unsafe {
stuff.set_len(4);
}
stuff
}
};

bob.meets(&mut susan);

println!("\nbob has {} `siblings` before entering the `bar`.", bob.siblings.len());
println!("\nthis is bob's address: {:p}", &bob);
let bar = Bar { person: bob };
bar.addr();
}

结果:

bob has 2 `siblings` before entering the `bar`.

this is bob's address: 0x7fff556ab470

`bob.siblings.len()`: 2, `bob.susan.siblings.len()`: 4

but wait -> `bob.susan.bob.siblings.len()`: 0 ??

this is `bob.susan.bob's address`: 0x7fff556ab470 => same address inside bar ???

我的问题是,bob.siblings 去了哪里?即使我通过 susan 调用 bob.siblings (bob.mate.mate.siblings -> bob.susan.bob .siblings), 结果不应该一样吗?

如何调用 bob.susan.bob.siblings 并获得与调用 bob.siblings 相同的结果?

Rust 版本:rustc 1.0.0-nightly (270a677d4 2015-03-07)(内置 2015-03-07)

最佳答案

这将是 Rust 帮助防止什么的一个很好的例子,但是你故意关闭了安全检查,现在我们回到 C。检查这一行:

let bar = Bar { person: bob };

这一行移动存储在bob中的数据到bar中。这意味着指针已无效,您不能信任任何值。让我们在之后添加:

println!("\nthis is bob's address: {:p}", &bob);
let bar = Bar { person: bob };
println!("\nthis is the bar's address: {:p}", &bar);
println!("\nthis is bob's new address: {:p}", &bar.person);

// this is bob's address: 0x7fffe10518c0
// this is the bar's address: 0x7fffe10517d0
// this is bob's new address: 0x7fffe10517d0

当您试图争论哪些指针正确哪些不正确时,您现在正处于一个受伤的世界中!

解决这个问题的一种方法是不要移动 bob。相反,请引用:

struct Bar<'a> {
person: &'a Person,
}
// ...
let bar = Bar { person: &bob };

另一种方法是将 meets 移动到 bar 后调用:

let mut bar = Bar { person: bob };
bar.person.meets(&mut susan);

另一种是Box(或使用Arena)数据。然后数据没有分配到堆栈上,因此值的地址在移动时不会改变:

struct Bar {
person: Box<Person>,
}
// ...
let mut bob = Box::new(Person { });
let mut susan = Box::new(Person { });

关于rust - 原始指针的数据消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28976259/

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