use std::alloc::Layout;
use crate::{
header::{AllocationHeader, HEADER_SIZE},
DeallocationError,
};
pub unsafe fn free(ptr: *mut u8) -> Result<(), DeallocationError> {
if ptr.is_null() {
return Err(DeallocationError::NullPtr);
}
if !(ptr as usize).is_multiple_of(HEADER_SIZE) {
return Err(DeallocationError::ImproperAlignment);
}
let header_ptr: *mut AllocationHeader = ptr.sub(HEADER_SIZE).cast();
if !header_ptr.is_aligned() {
return Err(DeallocationError::ImproperAlignment);
}
if (*header_ptr).is_marked_as_free() {
return Err(DeallocationError::DoubleFree);
}
if !(*header_ptr).is_marked_as_used() {
return Err(DeallocationError::CorruptedMarker);
}
let layout = Layout::from_size_align((*header_ptr).get_size(), HEADER_SIZE)?;
(*header_ptr).mark_as_free();
unsafe { std::alloc::dealloc(header_ptr.cast(), layout) }
Ok(())
}