11#include " malloc_from_scratch/memory_allocator.h"
2+ #include " malloc_from_scratch/memory_internal.h"
3+
4+ #include < cstdlib>
5+ #include < unistd.h>
26
37namespace mem
48{
@@ -9,6 +13,97 @@ void free(void* ptr)
913 {
1014 return ;
1115 }
16+
17+ void * current_program_break = sbrk (0 );
18+
19+ if (ptr < internal::heap_start || ptr >= current_program_break)
20+ {
21+ return ;
22+ }
23+
24+ internal::MemoryBlock* block_to_free = internal::getMetadata (ptr);
25+ if (block_to_free == nullptr || block_to_free->allocated_ == false )
26+ {
27+ return ;
28+ }
29+ block_to_free->allocated_ = false ;
30+
31+ internal::mergeFreeMemoryBlocks ();
32+
33+ internal::MemoryBlock* block_list_tail = nullptr ;
34+ internal::MemoryBlock* block_previous_from_last = nullptr ;
35+
36+ internal::getLastMemoryBlock (&block_list_tail, &block_previous_from_last);
37+ if (block_list_tail != nullptr && block_list_tail->allocated_ == false )
38+ {
39+ if (block_previous_from_last != nullptr )
40+ {
41+ block_previous_from_last->next_ = nullptr ;
42+ }
43+ else
44+ {
45+ internal::block_list_head = nullptr ;
46+ }
47+ internal::decreaseHeap (block_list_tail);
48+ }
49+ }
50+
51+ namespace internal
52+ {
53+
54+ void decreaseHeap (MemoryBlock* block_heap_end)
55+ {
56+ if (block_heap_end == nullptr )
57+ {
58+ return ;
59+ }
60+ if (block_heap_end->next_ != nullptr )
61+ {
62+ return ;
63+ }
64+
65+ size_t release_size = block_heap_end->size_ + BLOCK_METADATA_SIZE;
66+ void * program_break = sbrk (-static_cast <intptr_t >(release_size));
67+
68+ if (program_break == getErrorCodeInVoidPtr (-1 ) || program_break == getErrorCodeInVoidPtr (0 ))
69+ {
70+ exit (-1 );
71+ }
72+
73+ total_memory_allocated -= release_size;
74+ }
75+
76+ void mergeFreeMemoryBlocks ()
77+ {
78+ MemoryBlock* current = block_list_head;
79+ while (current != nullptr && current->next_ != nullptr )
80+ {
81+ if (current->allocated_ == false && current->next_ ->allocated_ == false )
82+ {
83+ current->size_ += BLOCK_METADATA_SIZE + current->next_ ->size_ ;
84+ current->next_ = current->next_ ->next_ ;
85+ }
86+ else
87+ {
88+ current = current->next_ ;
89+ }
90+ }
91+ }
92+
93+ void getLastMemoryBlock (MemoryBlock** block_list_tail, MemoryBlock** block_previous_from_last)
94+ {
95+ MemoryBlock* current = block_list_head;
96+ MemoryBlock* previous = nullptr ;
97+
98+ while (current != nullptr && current->next_ != nullptr )
99+ {
100+ previous = current;
101+ current = current->next_ ;
102+ }
103+
104+ *block_list_tail = current;
105+ *block_previous_from_last = previous;
12106}
13107
108+ } // namespace internal
14109} // namespace mem
0 commit comments