diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-27 11:45:06 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-27 11:45:06 +0100 |
| commit | 5ba7a73f97fe6880dc5328807a1cb9353e77b863 (patch) | |
| tree | eecedfad2887dc717d1771ed3e7a9bc8b7ba1ff7 /src/free.c | |
| parent | fb19b1c35f6ec52c075b214d2f0416900a7c1bbe (diff) | |
| download | malloc-5ba7a73f97fe6880dc5328807a1cb9353e77b863.tar.gz malloc-5ba7a73f97fe6880dc5328807a1cb9353e77b863.zip | |
Implement free and add testing notes to README
free now locates the chunk matching the pointer, marks it as
free for TINY/SMALL zones, and munmaps LARGE allocations.
Document why ASan is incompatible and list alternatives.
Diffstat (limited to 'src/free.c')
| -rw-r--r-- | src/free.c | 61 |
1 files changed, 57 insertions, 4 deletions
@@ -1,14 +1,67 @@ /** * @file free.c - * @brief Stub implementation of free. + * @brief free implementation. */ -#include "libft.h" #include "malloc.h" +#include "malloc_internal.h" +#include <sys/mman.h> + +static t_chunk * +_s_find_chunk (t_zone *zone, void *ptr) +{ + t_chunk *chunk; + + while (zone) + { + chunk = (t_chunk *)((char *)zone + ALIGN (sizeof (t_zone))); + while (chunk) + { + if ((char *)chunk + ALIGN (sizeof (t_chunk)) == ptr) + return (chunk); + chunk = chunk->next; + } + zone = zone->next; + } + return (NULL); +} + +static void +_s_unlink_zone (t_zone **zone_list, t_zone *zone) +{ + t_zone *prev; + + if (*zone_list == zone) + { + *zone_list = zone->next; + return; + } + prev = *zone_list; + while (prev && prev->next != zone) + prev = prev->next; + if (prev) + prev->next = zone->next; +} void free (void *ptr) { - (void)ptr; - ft_putendl_fd ("FREE", 1); + t_chunk *chunk; + t_zone *zone; + + if (!ptr) + return; + chunk = _s_find_chunk (g_heap.large, ptr); + if (chunk) + { + zone = (t_zone *)((char *)chunk - ALIGN (sizeof (t_zone))); + _s_unlink_zone (&g_heap.large, zone); + munmap (zone, zone->size); + return; + } + chunk = _s_find_chunk (g_heap.tiny, ptr); + if (!chunk) + chunk = _s_find_chunk (g_heap.small, ptr); + if (chunk) + chunk->is_free = 1; } |
