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

Rust 为什么创建和写入一个非常大的向量会导致核心转储?,rust,coredump,Rust,Coredump,我正在制作一个埃拉托斯烯筛,这样我就可以看到所有的素数,直到起始数。下面的代码会在Rust 1.26上导致内核转储。没有编译器警告或错误,核心转储也没有什么帮助,没有错误消息 fn main() { let starting_number: i64 = 600851475143; let mut primes = vec![true; 600851475143]; primes[0] = false; primes[1] = false; for i

我正在制作一个埃拉托斯烯筛,这样我就可以看到所有的素数,直到起始数。下面的代码会在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;
            }
        }
    }
}
fn main(){
let起始编号:i64=600851475143;
让mut primes=vec![true;600851475143];
素数[0]=假;
素数[1]=假;
对于2..(起始编号为f64).ln()为usize)中的i{
如果素数[i]{
设mut j=i+i;
而j

我以为生锈是为了安全和避免堆芯倾倒?这是我的代码中没有被编译器捕获的合法错误还是其他错误?

问题是内存不足

许多操作系统“懒惰”地分配内存。这意味着在您使用之前,操作系统不会实际分配您要求的实际内存量。您要求的是至少
75 106 434 393
(又称70 Gio),但是,您要求的是
600 851 475 143
字节(又称600 GiB)-您的操作系统一定没有找到足够的内存

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

我以为生锈是为了安全和避免堆芯倾倒

核心转储并不一定意味着程序不安全。正如您所看到的,您的程序没有进行越界内存访问,它只是没有足够的内存。从操作系统的角度来看,这是处理此错误的最佳方法,根据Rust中“安全”的定义,没有什么不安全的


顺便说一句,在我的机器(archlinux)上,您的程序被简单地终止:

[1]4901空载货物运行

你是说你的机器有超过1 TB的内存?我哪里都没说过?你的密码说了。你想分配一个超过6000亿布尔数的数组。它需要大量的内存。所以首先把这个数字缩小一点,看看这是否是问题所在。“我以为生锈是为了安全和避免堆芯倾倒?”-不,是为了安全和避免未定义的行为。程序突然中止是安全的,并已定义。锈试图减少这些,但它们决不是不可能的。在许多情况下,没有其他安全措施。与实际问题正交:你确定那里有
ln()
(又称自然对数)吗?我觉得你的意思是
sqrt()
,因为有很多非素数,其中没有任何除数小于
ln(n)
。还要注意的是,您的数字类型有点错误:(a)为什么您的起始编号不是u64?(b) 并非
i64
u64
中的所有数字都可以精确表示为
f64
,因此会降低精度。(c) 您可以在一个点上使用
usize
;在这些情况下,您不应该使用
usize
,而应该使用
u64
。在回答的开头说明实际问题(特别是OP试图分配大约600GiB)可能是值得的。。。这对你来说可能很明显,但对其他人(包括OP)来说不一定。我也不太明白,为什么要用八位字节来命名内存量。至少我从不关心八位字节的数目,我认为它不是一个非常直观的单位。@ Lukaskalbtotdt我相信Stargateur希望避免使用“字节”,因为在C和C++中,一个字节不一定是由8位组成的。不过,由于这不是C和C++,更可读的度量方法就可以了。@ EnNET4:我想这是因为它是法语字节的意思。@斯塔盖尔,好吧,我误解了。但是,还有一个小错误:
Vec
占用的字节数与
Vec
占用的字节数相同
Vec
不是专用于
std::vector
。所以不需要除以8。是的,我认为“字节”更容易理解:p它不能优化大小——它不能同时允许对元素的可变引用。如果需要节省空间,请使用
BitVec