use core::mem; use libc::{c_void, size_t}; /// Malloc memory if pointer is null, and free on drop pub struct MallocNull<T> { value: *mut T, free_on_drop: bool } impl<T> MallocNull<T> { pub fn new(ptr: *mut T, size: usize) -> MallocNull<T> { if ptr.is_null() { MallocNull { value: unsafe { ::malloc(size as size_t) as *mut T }, free_on_drop: true } } else { MallocNull { value: ptr, free_on_drop: false } } } pub fn into_raw(self) -> *mut T { let ptr = self.value; mem::forget(self); ptr } pub fn as_ptr(&self) -> *const T { self.value } pub fn as_mut_ptr(&self) -> *mut T { self.value } } impl<T> Drop for MallocNull<T> { fn drop(&mut self) { if self.free_on_drop { unsafe { ::free(self.value as *mut c_void) }; } } }