我在Debian操作系统上运行一个带有递归调用的程序。我的堆栈大小为
-s: stack size (kbytes) 8192
据我所知,堆栈大小必须是固定的,并且在每次运行程序时应该分配相同的大小,除非使用ulimit
明确更改它。
递归函数将给定数字递减,直到达到0
。这是用Rust编写的。
fn print_till_zero(x: &mut i32) {
*x -= 1;
println!("Variable is {}", *x);
while *x != 0 {
print_till_zero(x);
}
}
并将该值作为参数传递
static mut Y: i32 = 999999999;
unsafe {
print_till_zero(&mut Y);
}
由于程序分配的堆栈是固定的,并且理论上不应该改变,我预期每次都会在相同的值处发生堆栈溢出,但事实并非如此,这意味着堆栈分配是可变的。
运行1:
====snip====
Variable is 999895412
Variable is 999895411
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
跑酷2:
====snip====
Variable is 999895352
Variable is 999895351
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
虽然差异微妙,但最理想的情况不是应该在同一变量处引起堆栈溢出吗?为什么它会在不同的时间发生,意味着每次运行的堆栈大小不同?这不是 Rust 特有的;在 C 中也观察到类似的行为:
#pragma GCC push_options
#pragma GCC optimize ("O0")
#include<stdio.h>
void rec(int i){
printf("%d,",i);
rec(i-1);
fflush(stdout);
}
int main(){
setbuf(stdout,NULL);
rec(1000000);
}
#pragma GCC pop_options
输出:
运行 1:
738551,738550,[1] 7052 segmentation fault
第二轮:
738438,738437,[1] 7125 segmentation fault
unsafe
代码的必要性。 - Shepmaster