1use std::alloc::Layout;
2
3use crate::{
4 header::{AllocationHeader, HEADER_SIZE},
5 DeallocationError,
6};
7
8pub unsafe fn free(ptr: *mut u8) -> Result<(), DeallocationError> {
23 if ptr.is_null() {
24 return Err(DeallocationError::NullPtr);
25 }
26
27 if !(ptr as usize).is_multiple_of(HEADER_SIZE) {
28 return Err(DeallocationError::ImproperAlignment);
29 }
30
31 let header_ptr: *mut AllocationHeader = ptr.sub(HEADER_SIZE).cast();
32
33 if !header_ptr.is_aligned() {
34 return Err(DeallocationError::ImproperAlignment);
35 }
36
37 if (*header_ptr).is_marked_as_free() {
38 return Err(DeallocationError::DoubleFree);
39 }
40
41 if !(*header_ptr).is_marked_as_used() {
42 return Err(DeallocationError::CorruptedMarker);
43 }
44
45 let layout = Layout::from_size_align((*header_ptr).get_size(), HEADER_SIZE)?;
46
47 (*header_ptr).mark_as_free();
48
49 unsafe { std::alloc::dealloc(header_ptr.cast(), layout) }
50
51 Ok(())
52}