//! A minimal alternative to crates like `malloc_buf`, `mbox` and `malloced`. use core::ffi::c_char; use core::ffi::CStr; use core::fmt; use core::marker::PhantomData; use core::ops::Deref; use core::ptr::{self, NonNull};
impl<T> MallocSlice<T> { pub(crate) unsafefn from_array(mut ptr: *mut T, len: usize) -> Self { // If the length is 0, the pointer is usually NULL, and as such we // need to conjure some other pointer (slices are always non-null). if len == 0 {
ptr = NonNull::dangling().as_ptr();
}
let ptr = ptr::slice_from_raw_parts_mut(ptr, len); let ptr = NonNull::new(ptr).expect("tried to construct MallocSlice from a NULL pointer"); Self {
ptr,
_p: PhantomData,
}
}
fn len(&self) -> usize { // TODO: Use `self.ptr.len()` once in MSRV
(**self).len()
}
}
impl<T> Drop for MallocSlice<T> { #[allow(clippy::len_zero)] fn drop(&mutself) { // If the length is 0, then the pointer is dangling from `from_array` // (since the length is immutable), and we can skip calling `free`. ifself.len() != 0 { // SAFETY: We take ownership over the slice elements in // `from_array`. unsafe { ptr::drop_in_place(self.ptr.as_ptr()) }; // SAFETY: We take ownership over the pointer in `from_array`, // and the pointer is valid if the length is non-zero. unsafe { ffi::free(self.ptr.cast().as_ptr()) };
}
}
}
impl<T> Deref for MallocSlice<T> { type Target = [T];
#[inline] fn deref(&self) -> &[T] { // SAFETY: // - That the pointer is aligned, dereferenceable and initialized is // ensured by the caller of `from_array` (which usually get it from // some external API that will do this for you). // - The lifetime is bound to the `MallocSlice`, which in turn ensures // the pointer is valid until it is dropped. unsafe { self.ptr.as_ref() }
}
}
impl MallocCStr { pub(crate) unsafefn from_c_str(ptr: *mut c_char) -> Self { if ptr.is_null() {
panic!("tried to construct MallocStr from a NULL pointer");
} // SAFETY: We just checked that the pointer is not NULL. // // Further validity of the pointer is ensured by the caller. let cstr = unsafe { CStr::from_ptr(ptr) }; // Note that we construct this `NonNull` from an immutable reference // (there is not yet a `CStr::from_mut_ptr`). // // This means that we're (probably) no longer allowed to mutate the // value, if that is desired for `MallocStr` in the future, then we'll // have to implement this method a bit differently. let ptr = NonNull::from(cstr); Self { ptr }
}
}
impl Drop for MallocCStr { #[inline] fn drop(&mutself) { // SAFETY: We take ownership in `from_c_str`. unsafe { ffi::free(self.ptr.cast().as_ptr()) };
}
}
impl Deref for MallocCStr { type Target = CStr;
#[inline] fn deref(&self) -> &CStr { // SAFETY: Same as `MallocSlice::deref` unsafe { self.ptr.as_ref() }
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.