无递归无循环的Rust代码为何触发栈溢出?
Rust代码栈溢出的原因及修复方案
问题根源
你的代码触发栈溢出的核心原因并非循环或递归,而是你在栈上分配了过大的数组——栈的空间极其有限(Windows默认仅1MB,Linux一般为8MB),而你的数据结构远超这个限制:
- 计算内存占用:
SlidingAttackTable::Bishop的数组:64 * 512 * 8字节 = 256KBSlidingAttackTable::Rook的数组:64 * 4096 * 8字节 = 2MB- 加上返回的另外3个数组,总内存超过2.25MB,直接超出Windows默认栈大小,导致程序在进入
main函数、执行栈分配时就崩溃,连println!("start")都没机会执行。
修复方案
最直接的解决方法是把大数组转移到堆上,Rust中用Box实现堆分配,只在栈上保留一个指向堆数据的指针:
enum SlidingAttackTable { // 用Box包裹大数组,将数据移到堆上 Rook(Box<[[u64; 4096]; 64]>), Bishop(Box<[[u64; 512]; 64]>), } fn init_all() -> (SlidingAttackTable, SlidingAttackTable, [u64; 64], [u64; 64], [usize; 64]) { ( SlidingAttackTable::Bishop(Box::new([[0; 512]; 64])), SlidingAttackTable::Rook(Box::new([[0; 4096]; 64])), [0; 64], [0; 64], [0; 64], ) } fn main() { println!("start"); let _ = init_all(); }
其他可选方案
- 静态存储区分配:如果这些表是全局只读的,可以用
static关键字将其放到静态存储区,完全不占用栈/堆的运行时空间,适合预初始化的常量数据。 - 调整栈大小:部分平台支持通过编译选项调整栈大小(比如Linux下用
rustc -C link-args="-Wl,-z,stack-size=8388608"),但这种方法跨平台兼容性差,不推荐作为通用解决方案。
内容的提问来源于stack exchange,提问作者UnoriginalName369636
相关产品推荐
相关产品推荐

