aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/realloc.c36
-rw-r--r--tests/src/test_random.c104
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);
}