Search code examples
rustcoredump

Why does creating and writing to a very large vector cause a core dump?


I'm creating a Sieve of Eratosthenes so I can see all the prime numbers up to the starting number. Just the following code causes a core dump on Rust 1.26. There are no compiler warnings or errors, and the core dump isn't very helpful either with no error message.

fn main() {
    let starting_number: i64 = 600851475143;
    let mut primes = vec![true; 600851475143];

    primes[0] = false;
    primes[1] = false;

    for i in 2..((starting_number as f64).ln() as usize) {
        if primes[i] {
            let mut j = i + i;
            while j < primes.len() {
                primes[j] = false;
                j += i;
            }
        }
    }
}

I thought Rust was all about safety and avoiding core dumps? Is this a legit error with my code which isn't caught by the compiler or something different?


Solution

  • The problem is that you run out of memory.

    A lot of operating systems are "lazy" to allocate memory. This means that the OS will not actually allocate the real amount of memory you ask for until you use it. You are asking for at least 75 106 434 393 octets (a.k.a. 70 Gio) but Rust don't optimize the size of Vec<bool>, so you are asking for 600 851 475 143 bytes (a.k.a. 600 GiB) — your OS must not have found enough memory.

    It's an error that your OS can't handle because it already told you "OK" when you asked for the memory. It's a critical error, so it ends your process with a core dump.

    I thought Rust was all about safety and avoiding core dumps?

    A core dump doesn't necessarily imply that your program is not safe. As you see, your program didn't do an out of bounds memory access, it just doesn't have enough memory. It's the best way to handle this error from your OS point of view and there is nothing unsafe according to the definition of safe in Rust.


    BTW, on my machine (archlinux), your program is simply killed:

    [1]    4901 killed     cargo run