From 55d5a485a364a224dbb8800e74c2b96f87eb255a Mon Sep 17 00:00:00 2001 From: Gregory Date: Sun, 5 May 2019 19:30:06 +0300 Subject: [PATCH] malloc and free seem like done --- src/free.c | 26 +++++++++++++++++-- src/malloc.c | 42 ++++++++++++++---------------- subprojects/libft/ft_putchar.c | 3 ++- subprojects/libft/ft_putchar_fd.c | 3 ++- subprojects/libft/ft_putendl.c | 6 +++-- subprojects/libft/ft_putendl_fd.c | 6 +++-- subprojects/libft/ft_putstr.c | 3 ++- subprojects/libft/ft_putstr_fd.c | 3 ++- t/malloc_tests.c | 43 ++++++++++++++++++++++++++++++- 9 files changed, 101 insertions(+), 34 deletions(-) diff --git a/src/free.c b/src/free.c index 7932342..0684ff7 100644 --- a/src/free.c +++ b/src/free.c @@ -1,7 +1,29 @@ #include "ft_malloc.h" +#include "ft_malloc_internal.h" void free(void *used) { - (void)used; - return ; + t_chunk *chunk; + + if (!used) + return ; + chunk = (t_chunk *)used - 1; + if (chunk->magic != MAGIC) + return ; + chunk->is_free = 1; + if (chunk->prev && chunk->prev->is_free) + { + chunk->prev->size += chunk->size; + chunk->prev->next = chunk->next; + if (chunk->next) + chunk->next->prev = chunk->prev; + chunk = chunk->prev; + } + if (chunk->next && chunk->next->is_free) + { + chunk->size += chunk->next->size; + chunk->next = chunk->next->next; + if (chunk->next) + chunk->next->prev = chunk; + } } diff --git a/src/malloc.c b/src/malloc.c index 4ddf5e1..34a5895 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -5,20 +5,6 @@ t_arena g_base = { .type = START, .size = 0, .next = &g_base, .heap = NULL}; -static void add_arena(t_arena *arena, size_t size, int arena_type) -{ - arena->size = size; - arena->type = arena_type; - arena->heap = (t_chunk *)(arena + 1); - arena->heap->is_free = 1; - arena->heap->magic = MAGIC; - arena->heap->size = HEAP_SIZE(size); - arena->heap->next = NULL; - arena->heap->prev = NULL; - arena->next = g_base.next; - g_base.next = arena; -} - static size_t get_actual_size(size_t size, int type) { size_t minimum; @@ -52,7 +38,16 @@ static t_arena *get_more_arena(size_t size, int type) flags = MAP_ANON | MAP_PRIVATE; if ((arena = mmap(NULL, size, prot, flags, -1, 0)) == MAP_FAILED) return (NULL); - add_arena(arena, size, type); + arena->size = size; + arena->type = type; + arena->heap = (t_chunk *)(arena + 1); + arena->heap->is_free = 1; + arena->heap->magic = MAGIC; + arena->heap->size = HEAP_SIZE(size); + arena->heap->next = NULL; + arena->heap->prev = NULL; + arena->next = g_base.next; + g_base.next = arena; return (arena); } @@ -72,16 +67,17 @@ static t_chunk *chunk_heap(t_chunk *chunk, size_t size) new_chunk->size = size; new_chunk->next = chunk->next; new_chunk->prev = chunk; + new_chunk->prev->next = new_chunk; if (new_chunk->next) new_chunk->next->prev = new_chunk; - return (chunk); + return (new_chunk); } void *malloc(size_t size) { - void *space; t_arena *arena; - t_chunk *chunk; + t_chunk *heap; + t_chunk *space; int arena_type; space = NULL; @@ -90,12 +86,12 @@ void *malloc(size_t size) arena_type = get_arena_type(size); while(!space) { - if(arena->type == arena_type && (chunk = arena->heap)) - while(!space && chunk) + if(arena->type == arena_type && (heap = arena->heap)) + while(!space && heap) { - if (chunk->size >= size && chunk->is_free) - space = chunk_heap(chunk, size); - chunk = chunk->next; + if (heap->size >= size && heap->is_free) + space = chunk_heap(heap, size); + heap = heap->next; } arena = arena->next; if (!space && arena == &g_base) diff --git a/subprojects/libft/ft_putchar.c b/subprojects/libft/ft_putchar.c index daac03e..35c5c4b 100644 --- a/subprojects/libft/ft_putchar.c +++ b/subprojects/libft/ft_putchar.c @@ -14,5 +14,6 @@ void ft_putchar(char c) { - write(1, &c, 1); + if (write(1, &c, 1) == -1) + return ; } diff --git a/subprojects/libft/ft_putchar_fd.c b/subprojects/libft/ft_putchar_fd.c index 2349170..4d43fa4 100644 --- a/subprojects/libft/ft_putchar_fd.c +++ b/subprojects/libft/ft_putchar_fd.c @@ -14,5 +14,6 @@ void ft_putchar_fd(char c, int fd) { - write(fd, &c, 1); + if (write(fd, &c, 1) == -1) + return ; } diff --git a/subprojects/libft/ft_putendl.c b/subprojects/libft/ft_putendl.c index e9d9f3d..22addaa 100644 --- a/subprojects/libft/ft_putendl.c +++ b/subprojects/libft/ft_putendl.c @@ -16,6 +16,8 @@ void ft_putendl(char const *s) { if (s) while (*s) - write(1, s++, 1); - write(1, "\n", 1); + if (write(1, s++, 1) == -1) + return ; + if (write(1, "\n", 1) == -1) + return ; } diff --git a/subprojects/libft/ft_putendl_fd.c b/subprojects/libft/ft_putendl_fd.c index 45c78a7..5eee2d4 100644 --- a/subprojects/libft/ft_putendl_fd.c +++ b/subprojects/libft/ft_putendl_fd.c @@ -16,6 +16,8 @@ void ft_putendl_fd(char const *s, int fd) { if (s) while (*s) - write(fd, s++, 1); - write(fd, "\n", 1); + if(write(fd, s++, 1) == -1) + return ; + if(write(fd, "\n", 1) == -1) + return ; } diff --git a/subprojects/libft/ft_putstr.c b/subprojects/libft/ft_putstr.c index bbe80cb..c62c6a9 100644 --- a/subprojects/libft/ft_putstr.c +++ b/subprojects/libft/ft_putstr.c @@ -16,5 +16,6 @@ void ft_putstr(char const *s) { if (s) while (*s) - write(1, s++, 1); + if (write(1, s++, 1) == -1) + return ; } diff --git a/subprojects/libft/ft_putstr_fd.c b/subprojects/libft/ft_putstr_fd.c index 7f7f74f..91fe0c4 100644 --- a/subprojects/libft/ft_putstr_fd.c +++ b/subprojects/libft/ft_putstr_fd.c @@ -16,5 +16,6 @@ void ft_putstr_fd(char const *s, int fd) { if (s) while (*s) - write(fd, s++, 1); + if (write(fd, s++, 1) == -1) + return ; } diff --git a/t/malloc_tests.c b/t/malloc_tests.c index bdf569d..6a7c5b9 100644 --- a/t/malloc_tests.c +++ b/t/malloc_tests.c @@ -11,16 +11,57 @@ int inital_base_next_point_to_itself(void) int returns_not_null_pointer(void) { - void *ptr; + t_chunk *ptr; + g_base.next = &g_base; ptr = malloc(10); _IS(ptr != NULL); + + ptr = ptr - 1; + _IS(ptr->is_free == 0); + _IS(ptr->size == 10 + sizeof(t_chunk)); + _IS(ptr->magic == MAGIC); + _IS(ptr->next == NULL); + _IS(ptr->prev != NULL); + _IS(ptr->prev->size > TINY * NALLOC && ptr->prev->size < SMALL * NALLOC); _END("returns_not_null_pointer"); } +int free_concatenates_andjustent_blocks(void) +{ + t_chunk *ptr; + t_chunk *next_malloc; + t_chunk *heap; + + g_base.next = &g_base; + ptr = malloc(10); + next_malloc = malloc(10); + + ptr -= 1; + next_malloc -= 1; + + free(ptr + 1); + + _IS(ptr->is_free == 1); + _IS(ptr->prev == next_malloc); + _IS(next_malloc->is_free == 0); + _IS(next_malloc->next == ptr); + _IS(next_malloc->prev->prev == NULL); + + heap = next_malloc->prev; + free(next_malloc + 1); + + _IS(heap->is_free == 1); + _IS(heap->prev == NULL); + _IS(heap->next == NULL); + + _END("free_concatenates_andjustent_blocks"); +} + int main(void) { _SHOULD(inital_base_next_point_to_itself); _SHOULD(returns_not_null_pointer); + _SHOULD(free_concatenates_andjustent_blocks); return 0; } \ No newline at end of file