How do I use lazy_static to initialize a large static array?

I have some large static arrays that I want to initialize during program startup using the lazy_static! macro, but unfortunately, I can’t find a way to avoid a stack overflow. The code is quite complex, but here is a trivial (and silly) example that illustrates the problem:

#[macro_use]
extern crate lazy_static;

lazy_static! {
    static ref FOO: [u64; 1_000_000] = {
        let mut result = [0u64; 1_000_000];
        for i in 0..1_000_000 {
            result[i as usize] = i * i;
        }
        result
    };
}

fn main() {
    println!("{}", FOO[1000]);
}

When I try to run the above program, I get a stack overflow. The reason is fairly obvious: In the initialization block for FOO, the variable result is stack-allocated, and too large. I initially thought that this problem could be solved simply by making result a boxed value, like this:

#[macro_use]
extern crate lazy_static;

lazy_static! {
    static ref FOO: [u64; 1_000_000] = {
        let mut result = Box::new([0u64; 1_000_000]);
        for i in 0..1_000_000 {
            result[i as usize] = i * i;
        }
        *result
    };
}

fn main() {
    println!("{}", FOO[1000]);
}

Unfortunately, this does not work. It seems like Rust still allocates the array on the stack before boxing it.

What’s the right way to do this?

This is somewhat of a known issue. But, is there a reason you need the static to be an array? Can you use a Box<[u64]> instead? Then your problem goes away entirely :slight_smile:.

1 Like