下面这段代码会爆栈:
const SIZE: usize = 64 * 4096;
fn main() {
let _boxed_big_arr = Box::new([0_i128; SIZE]);
}
哎?Box 不是分配到了堆上吗??
再仔细看看文档里面说的:
alloc::boxed::Box
pub fn new(x: T) -> Self
Allocates memory on the heap and then places x into it. This doesn't actually allocate if T is zero-sized.
也就是说,在将这个巨型数组放到堆上之前,需要在栈上先创建这个数组,之后才会将这个数组移动到堆上
整点汇编 (结果由 godbolt.org/ 生成)
example::main:
mov eax, 4194344
call __rust_probestack /* 这里是用堆栈探针进行检测,防止爆栈,
实际上我们的函数在这里就被停下了,但我们主要看的是
Box::new 先在栈上分配内存这一点,如果想要详细了解,可以参考下文 */
sub rsp, rax
lea rdi, [rsp + 24]
xor esi, esi
mov edx, 4194304 /* 哇,"豪"无人性 */
mov qword ptr [rsp], rdx /* 栈上遭殃了趴,应该是这样的趴... */
mov rax, qword ptr [rip + memset@GOTPCREL]
call rax
mov rdi, qword ptr [rsp]
mov esi, 8
call alloc::alloc::exchange_malloc /* 看个大概,不深究了 QwQ */
有关__rust_probestack 看不到具体实现,因为底层是调用的 C