You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 16:15:02