运行这个:

fn main() {
    std::iter::count(1i16, 3).collect::<Vec<i16>>();
}

我得到:



这就是我在运行时所期望的:
fn main() {
    std::iter::count(1i8, 3).collect::<Vec<i8>>();
}

但相反,我得到了这个:



此外,syslog 显示以下行:

最佳答案

这是一次有趣的冒险。
Iter::collect 只是调用 FromIterator::from_iter Vec 's implementation of FromIterator 向迭代器询问它的大小,然后分配内存:

let (lower, _) = iterator.size_hint();
let mut vector = Vec::with_capacity(lower);
Vec::with_capacity 计算内存的总大小并尝试分配它:
let size = capacity.checked_mul(mem::size_of::<T>())
               .expect("capacity overflow");
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
if ptr.is_null() { ::alloc::oom() } // Important!
在这种情况下, i8 占用 1 个字节,无限迭代器的下限是 std::uint::MAX 。相乘,那仍然是 std::uint::MAX 。当我们分配它时,我们得到一个空指针。
alloc::oom 被定义为简单地中止,这是由 非法指令 实现的!i16 具有不同行为的原因是因为它触发了 checked_mul 期望 - 您不能分配 std::uint::MAX * 2 字节!

在现代 Rust 中,示例将被编写为:
(1i16..).step_by(3).collect::<Vec<_>>();
(1i8..).step_by(3).collect::<Vec<_>>();
现在两者都以相同的方式失败:
memory allocation of 12297829382473034412 bytes failed
memory allocation of 6148914691236517206 bytes failed

关于linux - 在 iter::count 上运行收集时得到 "Illegal instruction",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27664956/

10-13 03:07