表在 Rust 中导致堆栈溢出

问题描述 投票:0回答:1

我正在用 Rust 创建一个国际象棋换位表。为此,我创建了一个

TranspositonEntry
,它记录了一个 u64,它代表一个位置的哈希值和一个实际上只是一个 u16 的移动。我想将 2^19 个条目存储到一个数组中,但是有一个问题。该数组导致堆栈溢出。

我认为数组的大小(以字节为单位)将是 10 * 2^19,或者刚刚超过 5mb,这不应该导致堆栈溢出。但是,我认为这是不正确的,因为我无法修复代码以免导致堆栈溢出。

一个小例子是

struct Move {
    val : u16
}

impl Move {
    const NULL : Self = Self {val : 0}; 
}

struct TranspositionEntry {
    mov : Move,
    hash : u64
}

impl TranspositionEntry {
    const NULL_ENTRY: Self = Self { mov : Move::NULL, hash : 0};
}

fn main() {
    let table = [TranspositionEntry::NULL_ENTRY; 524288];
}

我认为表不应该大到足以导致堆栈溢出,但它确实如此。

rust stack-overflow
1个回答
0
投票

默认堆栈大小比您想象的要小。在 Windows 上,默认情况下堆栈大小仅为 1 MiB。在 Linux 上,它通常为 8 MiB,您可以这样检查:

$ ulimit -s
8192

当您生成线程时,您可以指定不同的堆栈大小:

fn main() {
    let builder = thread::Builder::new().stack_size(32 * 1024); // 32 MiB

    let handler = builder.spawn(|| {
        // this should work now
        let table = [TranspositionEntry::NULL_ENTRY; 524288];
    }).unwrap();

    handler.join().unwrap();
}

但在这种情况下,更好的解决方案是在堆上分配表。

fn main() {
    let table = vec![TranspositionEntry::NULL_ENTRY; 524288];
}
© www.soinside.com 2019 - 2024. All rights reserved.