From 876da036e423b1ff0ca9162108734eb549f2ac1d Mon Sep 17 00:00:00 2001 From: Lokathor Date: Fri, 20 Sep 2019 09:01:23 -0600 Subject: [PATCH] zeroed out boxes --- src/allocation.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/allocation.rs b/src/allocation.rs index fd9cf30..344caa4 100644 --- a/src/allocation.rs +++ b/src/allocation.rs @@ -2,6 +2,8 @@ use super::*; use alloc::{boxed::Box, rc::Rc, sync::Arc, vec::Vec}; +use alloc::alloc::Layout; +use alloc::alloc::alloc_zeroed; /// As [`try_cast_box`](try_cast_box), but unwraps for you. #[inline] @@ -31,6 +33,29 @@ pub fn try_cast_box(input: Box) -> Result, (PodCastErr } } +/// Allocates a `Box` with all of the contents being zeroed out. +/// +/// This is not the same as using `Box::new(T::zeroed())`. With this function +/// the contents of the box never exists on the stack, so this can create very +/// large boxes without fear of a stack overflow. +#[inline] +pub fn try_zeroed_box() -> Result,()> { + let layout = Layout::from_size_align(size_of::(), align_of::()).unwrap(); + let ptr = unsafe { alloc_zeroed(layout) }; + if ptr.is_null() { + // we don't know what the error is because `alloc_zeroed` is a dumb API + Err(()) + } else { + Box::::from_raw(ptr) + } +} + +/// As [`try_zeroed_box`], but unwraps for you. +#[inline] +pub fn zeroed_box() -> Box { + try_zeroed_box().unwrap() +} + /// As [`try_cast_vec`](try_cast_vec), but unwraps for you. #[inline] pub fn cast_vec(input: Vec) -> Vec {