运行这个:
fn main() {
std::iter::count(1i16, 3).collect::<Vec<i16>>();
}
Run Code Online (Sandbox Code Playgroud)
我得到:
线程 '' 在 '容量溢出' 中恐慌,/home/tshepang/projects/rust/src/libcore/option.rs:329
这就是我在运行时所期望的:
fn main() {
std::iter::count(1i8, 3).collect::<Vec<i8>>();
}
Run Code Online (Sandbox Code Playgroud)
但相反,我得到了这个:
非法指令
此外,syslog 显示以下行:
12 月 27 日 08:31:08 thome 内核:[170925.955841] 陷阱:main[30631] 陷阱无效操作码 ip:7f60ab175470 sp:7fffbb116578 error:0 in main[7f60ab15c000+5b000]
这是一次有趣的冒险。
Iter::collect
简单地调用 FromIterator::from_iter
Vec
的实现FromIterator
向迭代器询问其大小,然后分配内存:
let (lower, _) = iterator.size_hint();
let mut vector = Vec::with_capacity(lower);
Run Code Online (Sandbox Code Playgroud)
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!
Run Code Online (Sandbox Code Playgroud)
在这种情况下,i8
占用 1 个字节,无限迭代器的下限是std::uint::MAX
。相乘,还是std::uint::MAX
。当我们分配它时,我们得到一个空指针。
alloc::oom
被定义为简单地中止,这是由非法指令实现的!
ani16
具有不同行为的原因是因为它触发了checked_mul
期望 - 您不能分配std::uint::MAX * 2
字节!
在现代 Rust 中,示例将被编写为:
let (lower, _) = iterator.size_hint();
let mut vector = Vec::with_capacity(lower);
Run Code Online (Sandbox Code Playgroud)
现在两者都以相同的方式失败:
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!
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
417 次 |
最近记录: |