运行这个:
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/