Rust编写简易虚拟机时出现栈溢出问题求助
问题根因分析
你遇到的栈溢出问题核心原因是ArcateMem结构体的内存设计不合理:
- 你定义的内存数组是
[Instr; 0xFFFF*0xFFFF],Instr是u8类型,0xFFFF * 0xFFFF = 4294836225,换算下来这个数组需要占用接近4GB的连续内存空间 - Rust默认的栈空间大小仅为几MB,而你直接把这个超大数组放在栈上分配,程序启动时初始化
ArcateMem::new()就会直接撑爆栈空间,所以报错指向main函数入口。
修复方案
1. 改造内存存储方式,避免栈上分配超大对象
把固定大小的数组改为堆上分配的Vec<Instr>,或者使用Box包裹数组,让大内存分配在堆上:
#[derive(Clone)] struct ArcateMem { mem: Vec<Instr>, } impl ArcateMem { const MEM_SIZE: usize = 0xFFFF * 0xFFFF; fn new() -> Self { ArcateMem { mem: vec![0; Self::MEM_SIZE], } } }
如果确实需要用固定大小数组,改为Box<[Instr; 0xFFFF*0xFFFF]>即可,同样是堆分配。
2. 修复内存拷贝问题
你当前的ArcateBus结构体直接持有ArcateMem的所有权,每次创建总线都会拷贝整个内存对象,效率极低且内存占用翻倍,改为持有可变引用即可:
struct ArcateBus<'a> { data: Instr, addr: i32, todo: Signals, mem : &'a mut ArcateMem, }
3. 修复load函数逻辑错误
你当前的循环条件for i in loc..prog.len()是错误的,当加载起始位置loc不为0时,循环次数会远小于程序长度,正确写法应该是遍历程序偏移,写入到对应内存位置:
fn load(&mut self, prog: Program, loc: usize) { for (offset, byte) in prog.into_iter().enumerate() { let addr = loc + offset; self.mem.mem[addr] = byte; println!("{:2x} -> {:12x}", byte, addr); } }
额外优化建议
如果你的虚拟机不需要用到完整4GB内存,可以先把内存大小改小,比如设置为64KB(0x10000),调试阶段内存占用会小很多,运行速度也更快。
内容的提问来源于stack exchange,提问作者ANTHONY STERLING-PALMARI
相关产品推荐
相关产品推荐

