diff options
| author | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-27 12:02:16 +0100 |
|---|---|---|
| committer | Thomas Vanbesien <tvanbesi@proton.me> | 2026-02-27 12:02:16 +0100 |
| commit | 25d16ff06c2551ed090c2847efdc819303e577f3 (patch) | |
| tree | 6823f9d9afa332a91de19a27722d53f12a12f15e | |
| parent | b8de4f339318dc245b073f05e186c4b2b1e8e758 (diff) | |
| download | malloc-25d16ff06c2551ed090c2847efdc819303e577f3.tar.gz malloc-25d16ff06c2551ed090c2847efdc819303e577f3.zip | |
Implement realloc and add realloc rounds to random test
realloc returns the same pointer if the chunk is large enough,
otherwise malloc + memcpy + free. The random test now verifies
data integrity after resizing across all three categories.
| -rw-r--r-- | src/realloc.c | 36 | ||||
| -rw-r--r-- | tests/src/test_random.c | 104 |
2 files changed, 134 insertions, 6 deletions
diff --git a/src/realloc.c b/src/realloc.c index c0bbfed..3cc92f1 100644 --- a/src/realloc.c +++ b/src/realloc.c @@ -1,16 +1,42 @@ /** * @file realloc.c - * @brief Stub implementation of realloc. + * @brief realloc implementation. */ #include "libft.h" #include "malloc.h" +#include "malloc_internal.h" + +static t_chunk * +_s_ptr_to_chunk (void *ptr) +{ + return ((t_chunk *)((char *)ptr - ALIGN (sizeof (t_chunk)))); +} void * realloc (void *ptr, size_t size) { - (void)ptr; - (void)size; - ft_putendl_fd ("REALLOC", 1); - return (NULL); + t_chunk *chunk; + void *new_ptr; + size_t copy_size; + + if (!ptr) + return (malloc (size)); + if (size == 0) + { + free (ptr); + return (NULL); + } + chunk = _s_ptr_to_chunk (ptr); + if (chunk->size >= ALIGN (size)) + return (ptr); + new_ptr = malloc (size); + if (!new_ptr) + return (NULL); + copy_size = chunk->size; + if (copy_size > size) + copy_size = size; + ft_memcpy (new_ptr, ptr, copy_size); + free (ptr); + return (new_ptr); } diff --git a/tests/src/test_random.c b/tests/src/test_random.c index f7247e2..396abf9 100644 --- a/tests/src/test_random.c +++ b/tests/src/test_random.c @@ -1,6 +1,6 @@ /** * @file test_random.c - * @brief Randomized correctness test for malloc/free. + * @brief Randomized correctness test for malloc/free/realloc. * * Allocates random-sized blocks in TINY, SMALL, and LARGE ranges, * fills them with a deterministic pattern, then verifies the data. @@ -138,6 +138,102 @@ _s_test_category (const char *label, size_t min, size_t max, int seed, } static int +_s_test_realloc (const char *label, size_t min, size_t max, int seed, + int base_index, int count) +{ + void *blocks[count]; + size_t sizes[count]; + size_t new_size; + size_t check_size; + unsigned char *data; + int fail; + int i; + int j; + + fail = 0; + i = 0; + while (i < count) + { + sizes[i] = _s_rand_range (min, max); + blocks[i] = malloc (sizes[i]); + if (!blocks[i]) + { + i++; + continue; + } + data = (unsigned char *)blocks[i]; + j = 0; + while (j < (int)sizes[i]) + { + data[j] = _s_pattern (seed, base_index + i, j); + j++; + } + i++; + } + i = 0; + while (i < count) + { + if (!blocks[i]) + { + i++; + continue; + } + new_size = _s_rand_range (min, max); + blocks[i] = realloc (blocks[i], new_size); + if (!blocks[i]) + { + _s_put_str (label); + _s_put_str ("["); + _s_put_nbr (i); + _s_put_str ("]: realloc FAILED\n"); + fail = 1; + i++; + continue; + } + check_size = sizes[i]; + if (new_size < check_size) + check_size = new_size; + data = (unsigned char *)blocks[i]; + j = 0; + while (j < (int)check_size) + { + if (data[j] != _s_pattern (seed, base_index + i, j)) + { + _s_put_str (label); + _s_put_str ("["); + _s_put_nbr (i); + _s_put_str ("]: FAIL at byte "); + _s_put_nbr (j); + _s_put_str ("\n"); + fail = 1; + break; + } + j++; + } + if (j == (int)check_size) + { + _s_put_str (label); + _s_put_str ("["); + _s_put_nbr (i); + _s_put_str ("]: OK ("); + _s_put_nbr ((int)sizes[i]); + _s_put_str (" -> "); + _s_put_nbr ((int)new_size); + _s_put_str (" bytes)\n"); + } + sizes[i] = new_size; + i++; + } + i = 0; + while (i < count) + { + free (blocks[i]); + i++; + } + return (fail); +} + +static int _s_atoi (const char *str) { int n; @@ -172,5 +268,11 @@ main (int argc, char **argv) count); fail |= _s_test_category ("LARGE", SMALL_MAX + 1, LARGE_MAX, seed, count * 2, count); + fail + |= _s_test_realloc ("REALLOC_TINY", 1, TINY_MAX, seed, count * 3, count); + fail |= _s_test_realloc ("REALLOC_SMALL", TINY_MAX + 1, SMALL_MAX, seed, + count * 4, count); + fail |= _s_test_realloc ("REALLOC_LARGE", SMALL_MAX + 1, LARGE_MAX, seed, + count * 5, count); return (fail); } |
