为什么创建和写入非常大的向量会导致核心转储?

Cor*_*ter -1 coredump rust

我正在创建一个Eratosthenes筛子,所以我可以看到所有素数到起始数字.只是下面的代码导致Rust 1.26上的核心转储.没有编译器警告或错误,并且核心转储对于没有错误消息也没有帮助.

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为Rust完全是为了安全并避免核心转储?这是一个合法的错误,我的代码没有被编译器捕获或不同的东西?

Sta*_*eur 5

问题是你的内存不足.

许多操作系统都"懒惰"来分配内存.这意味着在您使用之前,操作系统实际上不会分配您要求的实际内存量.你要求至少75 106 434 393 八位字节(又名70 Gio),但Rust没有优化大小Vec<bool>,所以你要求600 851 475 143字节(又名600 GiB) - 你的操作系统一定找不到足够的内存.

这是一个错误,你的操作系统无法处理,因为当你要求内存时它已经告诉你"OK".这是一个严重错误,因此它以核心转储结束您的流程.

我认为Rust完全是为了安全并避免核心转储?

核心转储并不一定意味着您的程序不安全.如您所见,您的程序没有进行超出内存访问,它只是没有足够的内存.从操作系统的角度来看,这是处理此错误的最佳方法,根据Rust中的安全定义,没有任何不安全的方法.


顺便说一句,在我的机器(archlinux)上,你的程序被杀死了:

[1]    4901 killed     cargo run
Run Code Online (Sandbox Code Playgroud)

  • *生锈不会优化尺寸* - 它仍然不允许对元素进行可变引用.如果您需要节省空间,可以使用"BitVec" (3认同)
  • @ E_net4:我认为这是因为它是法语中的字节. (2认同)
  • @Stargateur啊好吧,我误会了.但是你有一个小错误:`Vec <bool>`与`Vec <u8>`占用的字节数与元素数相同.`vec <bool>`不是专门用作`std :: vector <bool>`.所以不需要除以8.是的,我认为"字节"会更容易理解:P (2认同)