diff --git a/inc/ft_malloc.h b/inc/ft_malloc.h index 252b60c..a7a00f9 100644 --- a/inc/ft_malloc.h +++ b/inc/ft_malloc.h @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_malloc.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/05/06 22:37:16 by foton #+# #+# */ +/* Updated: 2019/05/06 22:40:14 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + #ifndef FT_MALLOC_H # define FT_MALLOC_H diff --git a/inc/ft_malloc_internal.h b/inc/ft_malloc_internal.h index d60a494..5de9584 100644 --- a/inc/ft_malloc_internal.h +++ b/inc/ft_malloc_internal.h @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_malloc_internal.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/05/06 22:37:07 by foton #+# #+# */ +/* Updated: 2019/05/06 22:40:18 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + #ifndef FT_MALLOC_INTERNAL_H # define FT_MALLOC_INTERNAL_H diff --git a/src/free.c b/src/free.c index 0684ff7..be98b6a 100644 --- a/src/free.c +++ b/src/free.c @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/05/06 22:35:53 by foton #+# #+# */ +/* Updated: 2019/05/06 22:40:09 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "ft_malloc.h" #include "ft_malloc_internal.h" diff --git a/src/malloc.c b/src/malloc.c index 6e0c7f8..17babd1 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -1,3 +1,15 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/05/06 22:35:57 by foton #+# #+# */ +/* Updated: 2019/05/07 22:06:49 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include #include "ft_malloc.h" #include "ft_malloc_internal.h" @@ -55,13 +67,13 @@ static t_chunk *chunk_heap(t_chunk *chunk, size_t size) { t_chunk *new_chunk; - if (chunk->size == size) + if (chunk->size == size || chunk->size - size < sizeof(t_chunk)) { chunk->is_free = 0; return (chunk); } chunk->size -= size; - new_chunk = (t_chunk *)((uint8_t *)chunk + chunk->size); + new_chunk = (t_chunk *)((size_t)chunk + chunk->size); new_chunk->is_free = 0; new_chunk->magic = MAGIC; new_chunk->size = size; diff --git a/src/realloc.c b/src/realloc.c index cf25e51..5c5111a 100644 --- a/src/realloc.c +++ b/src/realloc.c @@ -1,8 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* realloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/05/06 22:35:48 by foton #+# #+# */ +/* Updated: 2019/05/07 00:25:13 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + #include "ft_malloc.h" +#include "ft_malloc_internal.h" +#include "libft.h" void *realloc(void *ptr, size_t size) { - (void)ptr; - (void)size; - return (NULL); + t_chunk *chunk; + t_chunk *new_chunk; + + if (!ptr) + return (malloc(size)); + chunk = (t_chunk *)ptr - 1; + if (chunk->magic != MAGIC) + return (NULL); + if (chunk->size >= CHUNK_SIZE(size)) + return (ptr); + new_chunk = malloc(size); + ft_memmove(new_chunk, ptr, chunk->size - CHUNK_SIZE(0)); + free(ptr); + return (new_chunk); } \ No newline at end of file diff --git a/subprojects/libft/meson.build b/subprojects/libft/meson.build index 063ac96..7e79728 100644 --- a/subprojects/libft/meson.build +++ b/subprojects/libft/meson.build @@ -86,7 +86,6 @@ libft = static_library( 'ft', srcs, include_directories: inc, - # install : true, ) libft_dep = declare_dependency( diff --git a/t/fuzzy.c b/t/fuzzy.c new file mode 100644 index 0000000..b1002c8 --- /dev/null +++ b/t/fuzzy.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include + +struct item { + void *ptr; + size_t size; + size_t hash; +}; + +static void hash_compute(struct item *item) { + unsigned char c; + size_t hash = 0xdeadbeef; + + for (size_t i = 0; i < item->size; i++) { + c = rand(); + ((unsigned char *)item->ptr)[i] = c; + hash += (hash << 13) ^ c; + hash ^= (hash << 26) - (c * ((hash >> 56) + 1)); + } + item->hash = hash; +} + +static int hash_check(struct item *item) { + unsigned char c; + size_t hash = 0xdeadbeef; + + if (item->ptr == NULL) + return 1; + + for (size_t i = 0; i < item->size; i++) { + c = ((unsigned char *)item->ptr)[i]; + hash += (hash << 13) ^ c; + hash ^= (hash << 26) - (c * ((hash >> 56) + 1)); + } + return (item->hash == hash); +} + +int main(int argc, const char *const argv[]) { + if (argc < 4) { + puts("Usage: ... num_passes num_items size_min size_max"); + return 1; + } + + size_t num_passes = atoi(argv[1]), + num_items = atoi(argv[2]), + size_min = atoi(argv[3]), + size_max = atoi(argv[4]); + struct item items[num_items]; + + srand(argc + num_items + size_min + size_max); + srand(rand() ^ time(NULL)); + bzero(items, sizeof(struct item) * num_items); + + for (size_t pass = 0; pass < num_passes; pass++) { + for (size_t i = 0; i < num_items; i++) { + if (pass % 3 == 0) { + if (rand() & 1 && items[i].ptr == NULL) { + items[i].size = rand() % (size_max - size_min) + size_min; + items[i].ptr = malloc(items[i].size); + if (items[i].ptr) { + hash_compute(&items[i]); + printf("pass %-2lu item %-4lu malloc(%lu) => %p..%p\n", + pass, i, items[i].size, items[i].ptr, items[i].ptr + items[i].size); + } else { + printf("\033[0;31mpass %-2lu item %-4lu returned NULL\033[0m\n", pass, i); + } + } + } else if (pass % 3 == 1) { + if (rand() & 1 && items[i].ptr != NULL) { + void *old_ptr = items[i].ptr; + items[i].size = rand() % (size_max - size_min) + size_min; + items[i].ptr = realloc(items[i].ptr, items[i].size); + if (items[i].ptr) { + hash_compute(&items[i]); + printf("pass %-2lu item %-4lu realloc(%p, %lu) => %p\n", + pass, i, old_ptr, items[i].size, items[i].ptr); + } else { + printf("\033[0;31mpass %-2lu item %-4lu realloc failed\033[0m\n", pass, i); + } + } + } else { + if (rand() & 1 && items[i].ptr != NULL) { + printf("pass %-2lu item %-4lu free(%p)\n", + pass, i, items[i].ptr); + free(items[i].ptr); + items[i].ptr = NULL; + } else if (pass == num_passes - 1 && items[i].ptr != NULL) { + printf("pass %-2lu item %-4lu free(%p)\n", + pass, i, items[i].ptr); + free(items[i].ptr); + items[i].ptr = NULL; + } + } + + for (size_t j = 0; j < num_items; j++) { + if (!hash_check(&items[i])) { + printf("\033[0;31mpass %-2lu item %-4lu hash_check failed\033[0m\n", pass, i); + items[i].ptr = NULL; + } + } + } + + /* show_alloc_mem(); */ + } + return (0); +} diff --git a/t/malloc_tests.c b/t/malloc_tests.c index 6608be0..9b504b9 100644 --- a/t/malloc_tests.c +++ b/t/malloc_tests.c @@ -1,7 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc_tests.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: gtertysh +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/05/06 22:35:37 by foton #+# #+# */ +/* Updated: 2019/05/07 22:44:42 by gtertysh ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include #include "t.h" #include "ft_malloc.h" #include "ft_malloc_internal.h" -#include int inital_base_next_point_to_itself(void) { @@ -20,7 +32,7 @@ int returns_not_null_pointer(void) ptr = ptr - 1; _IS(ptr->is_free == 0); _IS(ptr->size == 10 + sizeof(t_chunk)); - // _IS(ptr->magic == MAGIC); + _IS(ptr->magic == MAGIC); _IS(ptr->next == NULL); _IS(ptr->prev != NULL); _IS(ptr->prev->size > TINY * NALLOC && ptr->prev->size < SMALL * NALLOC); @@ -64,6 +76,7 @@ int malloc_creates_new_arena(void) int chunks_count; int i; int page; + g_base.next = &g_base; page = getpagesize(); // minimum 100 chunks aligned to page size @@ -72,7 +85,7 @@ int malloc_creates_new_arena(void) i = 0; while (i < chunks_count) { - malloc(TINY); + second_arena_chunk = malloc(TINY); i++; } @@ -87,11 +100,25 @@ int malloc_creates_new_arena(void) _END("malloc_creates_new_arena"); } +int realloc_return_same_pointer(void) +{ + t_chunk *ptr; + t_chunk *new_ptr; + + g_base.next = &g_base; + ptr = malloc(20); + new_ptr = realloc(ptr, 10); + + _IS(ptr == new_ptr); + _END("realloc_return_same_pointer"); +} + int main(void) { _SHOULD(inital_base_next_point_to_itself); _SHOULD(returns_not_null_pointer); _SHOULD(free_concatenates_adjacent_blocks); _SHOULD(malloc_creates_new_arena); + _SHOULD(realloc_return_same_pointer); return 0; } \ No newline at end of file diff --git a/t/meson.build b/t/meson.build index 8099e0b..7ec568e 100644 --- a/t/meson.build +++ b/t/meson.build @@ -5,4 +5,14 @@ malloc_tests = executable( link_with: ft_malloc, ) -test('malloc tests', malloc_tests) \ No newline at end of file + +malloc_fuzzy_tests = executable( + 'malloc_fuzzy', + 'fuzzy.c', + include_directories: inc, + link_with: ft_malloc, +) + +test('malloc tests', malloc_tests) + +test('malloc fuzzy tests', malloc_fuzzy_tests, args: ['10', '1000', '0', '10000']) \ No newline at end of file