时,我有一个简单的例子锈的行为不符合我的精神形象,所以我想知道我缺少什么:堆栈行为返回一个指针到局部变量
fn make_local_int_ptr() -> *const i32 {
let a = 3;
&a
}
fn main() {
let my_ptr = make_local_int_ptr();
println!("{}", unsafe { *my_ptr });
}
结果:
3
这不是我所期望的。使用The Stack and the Heap
给出的符号我希望堆栈帧看起来像这样:
Address | Name | Value
-----------------------
0 | a | 3
内make_local_int_ptr()
,但此行之后,
let my_ptr = make_local_int_ptr();
由于a
超出范围,我期望堆栈被清除。但它显然没有。
而且,如果我定义创建my_ptr
并打印了它的提领值之间的另一个变量:
fn main() {
let my_ptr = make_local_int_ptr();
let b = 6;
println!("{}", b); // We have to use b otherwise Rust
// compiler ignores it (I think)
println!("{}", unsafe { *my_ptr });
}
我的输出是:
6
0
这又不是我所期待的,我是思考:
Address | Name | Value
-----------------------
0 | b | 6
在这种情况下,我的输出将是:
6
6
,甚至(在C++
和Go
我得到这样的结果):
Address | Name | Value
-----------------------
1 | b | 6
0 | a | 3
在这种情况下,我的输出是:
6
3
但为什么我收到的输出我正在接受?
此外,为什么返回一个指向本地变量的指针甚至允许?该变量超出范围,并且指针指向的值变得不可预知。
当一个函数有许多局部变量时,通常当函数开始时它们会一次性全部分配。因此,在调用'make_local_int_ptr'时,已经分配了'b'(即使它还不可用),所以'a'和'b'不会重叠。 –
[您租用酒店房间。你把书放在最上面的抽屉里。你第二天早上退房,但“忘记”放弃你的钥匙。一个星期后,你回到酒店,不要登记入住,用偷来的钥匙偷偷摸进你的旧房间,然后看着抽屉。你的书还在那里。惊人(http://stackoverflow.com/a/6445794/395760) – delnan
@delnan:即使到了现在,我只是喜欢这样的解释:) –