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

为何我的Safe Rust代码会触发段错误或栈溢出?

Safe Rust代码触发段错误/栈溢出的原因

问题代码

use std::mem::size_of;

const ROWS_PER_PAGE: usize = PAGE_SIZE / ROW_SIZE;
const TABLE_MAX_ROWS: usize = TABLE_MAX_PAGES * ROWS_PER_PAGE;
const ROW_SIZE: usize = ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;
const TABLE_MAX_PAGES: usize = 100;
const PAGE_SIZE: usize = 4096;
const ID_SIZE: usize = size_of::<u64>();
const USERNAME_SIZE: usize = 32;
const EMAIL_SIZE: usize = 255;

#[derive(Clone, Copy, Debug)]
pub struct Page {
    buffer: [u8; PAGE_SIZE],
}
pub struct Table {
    pub pages: [Option<Page>; TABLE_MAX_ROWS],
    pub num_rows: usize,
}

impl Table {
    pub fn new() -> Self {
        Self {
            pages: [None; TABLE_MAX_ROWS],
            num_rows: 0,
        }
    }
}

fn main() {
    println!("{}", ROW_SIZE);
    let table = Table::new();
    println!("{:p}", &table);
}

运行报错

在MacBook Pro(aarch64-apple-darwin nightly工具链)上运行:

$ cargo r
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
    Running `target/debug/segfault`
295
[1]    68684 segmentation fault 
$ rustup show active-toolchain       
nightly-aarch64-apple-darwin (default)

在Rust Playground运行时直接提示Stack overflow。

问题原因

核心是栈上分配了超大型数组:

  1. 计算常量值:
    • ROW_SIZE = 8 + 32 + 255 = 295
    • ROWS_PER_PAGE = 4096 / 295 = 13(整数除法取整)
    • TABLE_MAX_ROWS = 100 * 13 = 1300
  2. Table结构体中的pages是包含1300个Option<Page>的固定大小数组,每个Page本身占用4096字节内存,即使None状态的Option<Page>也会占用近似大小的内存(额外加1字节标记位)。
  3. 整个pages数组总内存占用约为1300 * 4097 ≈ 5.3MB,而程序栈空间通常仅几MB(macOS默认栈大小约8MB,debug模式下编译器额外开销会进一步压缩可用空间)。当main函数创建Table实例时,巨型数组直接分配在栈上,瞬间耗尽栈空间引发溢出——不同平台对栈溢出的表现不同,macOS触发段错误,Rust Playground直接检测并提示栈溢出。

解决方案

将大型数组从栈转移到堆上,比如用Vec<Option<Page>>替代固定大小数组:

// 修改Table结构体定义
pub struct Table {
    pub pages: Vec<Option<Page>>,
    pub num_rows: usize,
}

impl Table {
    pub fn new() -> Self {
        Self {
            // Vec会在堆上分配内存
            pages: vec![None; TABLE_MAX_ROWS],
            num_rows: 0,
        }
    }
}

这样数组内存会分配在堆上,栈上仅存储Vec的元数据(指针、长度、容量),不会再触发栈溢出问题。

内容的提问来源于stack exchange,提问作者Miss Yoimiya's puppy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 01:50:20