首页 文章

当使用Box分配大型数组时,线程'<main>'已溢出其堆栈

提问于
浏览
2

我正在实施combsort . 我想在堆栈上创建固定大小的数组,但它显示 stack overflow . 当我将它更改为在堆上时(Rust by Example表示to allocate in the heap we must use Box),它仍然显示 stack overflow .

fn new_gap(gap: usize) -> usize {
    let ngap = ((gap as f64) / 1.3) as usize;
    if ngap == 9 || ngap == 10 {
        return 11;
    }
    if ngap < 1 {
        return 1;
    }
    return ngap;
}

fn comb_sort(a: &mut Box<[f64]>) {
    // previously: [f64]
    let xlen = a.len();
    let mut gap = xlen;
    let mut swapped: bool;
    let mut temp: f64;
    loop {
        swapped = false;
        gap = new_gap(gap);
        for i in 0..(xlen - gap) {
            if a[i] > a[i + gap] {
                swapped = true;
                temp = a[i];
                a[i] = a[i + gap];
                a[i + gap] = temp;
            }
        }
        if !(gap > 1 || swapped) {
            break;
        }
    }
}

const N: usize = 10000000;

fn main() {
    let mut arr: Box<[f64]> = Box::new([0.0; N]); // previously: [f64; N] = [0.0; N];
    for z in 0..(N) {
        arr[z] = (N - z) as f64;
    }
    comb_sort(&mut arr);
    for z in 1..(N) {
        if arr[z] < arr[z - 1] {
            print!("!")
        }
    }
}

输出:

thread '<main>' has overflowed its stack
Illegal instruction (core dumped)

我知道我的堆栈大小不够,在创建函数内部太大的非堆数组时与C相同,但此代码使用堆但仍显示堆栈溢出 . 这段代码真的出了什么问题?

2 回答

  • 3

    据我所知,似乎代码仍在尝试首先在堆栈上分配数组,然后将其移入框中 .

    如果我切换到 Vec<f64> 代替 Box<[f64]> ,它对我有用:

    fn new_gap(gap: usize) -> usize {
        let ngap = ((gap as f64) / 1.3) as usize;
        if ngap == 9 || ngap == 10 {
            return 11;
        }
        if ngap < 1 {
            return 1;
        }
        return ngap;
    }
    
    fn comb_sort(a: &mut [f64]) {
        // previously: [f64]
        let xlen = a.len();
        let mut gap = xlen;
        let mut swapped: bool;
        let mut temp: f64;
        loop {
            swapped = false;
            gap = new_gap(gap);
            for i in 0..(xlen - gap) {
                if a[i] > a[i + gap] {
                    swapped = true;
                    temp = a[i];
                    a[i] = a[i + gap];
                    a[i + gap] = temp;
                }
            }
            if !(gap > 1 || swapped) {
                break;
            }
        }
    }
    
    const N: usize = 10000000;
    
    fn main() {
        let mut arr: Vec<f64> = std::iter::repeat(0.0).take(N).collect();
        //let mut arr: Box<[f64]> = Box::new([0.0; N]); // previously: [f64; N] = [0.0; N];
        for z in 0..(N) {
            arr[z] = (N - z) as f64;
        }
        comb_sort(arr.as_mut_slice());
        for z in 1..(N) {
            if arr[z] < arr[z - 1] {
                print!("!")
            }
        }
    }
    
  • 3

    将来, box 语法将会稳定下来 . 如果是,它将支持这种大的分配,因为不需要对 Box::new 的函数调用,因此数组永远不会被放置在堆栈上 . 例如:

    #![feature(box_syntax)]
    
    fn main() {
        let v = box [0i32; 5_000_000];
        println!("{}", v[1_000_000])
    }
    

相关问题