時,我有一個簡單的例子鏽的行爲不符合我的精神形象,所以我想知道我缺少什麼:堆棧行爲返回一個指針到局部變量
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:即使到了現在,我只是喜歡這樣的解釋:) –