malloc and free seem like done
This commit is contained in:
parent
902bc6d7f0
commit
55d5a485a3
9 changed files with 101 additions and 34 deletions
24
src/free.c
24
src/free.c
|
@ -1,7 +1,29 @@
|
||||||
#include "ft_malloc.h"
|
#include "ft_malloc.h"
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
|
||||||
void free(void *used)
|
void free(void *used)
|
||||||
{
|
{
|
||||||
(void)used;
|
t_chunk *chunk;
|
||||||
|
|
||||||
|
if (!used)
|
||||||
return ;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
42
src/malloc.c
42
src/malloc.c
|
@ -5,20 +5,6 @@
|
||||||
|
|
||||||
t_arena g_base = { .type = START, .size = 0, .next = &g_base, .heap = NULL};
|
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)
|
static size_t get_actual_size(size_t size, int type)
|
||||||
{
|
{
|
||||||
size_t minimum;
|
size_t minimum;
|
||||||
|
@ -52,7 +38,16 @@ static t_arena *get_more_arena(size_t size, int type)
|
||||||
flags = MAP_ANON | MAP_PRIVATE;
|
flags = MAP_ANON | MAP_PRIVATE;
|
||||||
if ((arena = mmap(NULL, size, prot, flags, -1, 0)) == MAP_FAILED)
|
if ((arena = mmap(NULL, size, prot, flags, -1, 0)) == MAP_FAILED)
|
||||||
return (NULL);
|
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);
|
return (arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,16 +67,17 @@ static t_chunk *chunk_heap(t_chunk *chunk, size_t size)
|
||||||
new_chunk->size = size;
|
new_chunk->size = size;
|
||||||
new_chunk->next = chunk->next;
|
new_chunk->next = chunk->next;
|
||||||
new_chunk->prev = chunk;
|
new_chunk->prev = chunk;
|
||||||
|
new_chunk->prev->next = new_chunk;
|
||||||
if (new_chunk->next)
|
if (new_chunk->next)
|
||||||
new_chunk->next->prev = new_chunk;
|
new_chunk->next->prev = new_chunk;
|
||||||
return (chunk);
|
return (new_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *malloc(size_t size)
|
void *malloc(size_t size)
|
||||||
{
|
{
|
||||||
void *space;
|
|
||||||
t_arena *arena;
|
t_arena *arena;
|
||||||
t_chunk *chunk;
|
t_chunk *heap;
|
||||||
|
t_chunk *space;
|
||||||
int arena_type;
|
int arena_type;
|
||||||
|
|
||||||
space = NULL;
|
space = NULL;
|
||||||
|
@ -90,12 +86,12 @@ void *malloc(size_t size)
|
||||||
arena_type = get_arena_type(size);
|
arena_type = get_arena_type(size);
|
||||||
while(!space)
|
while(!space)
|
||||||
{
|
{
|
||||||
if(arena->type == arena_type && (chunk = arena->heap))
|
if(arena->type == arena_type && (heap = arena->heap))
|
||||||
while(!space && chunk)
|
while(!space && heap)
|
||||||
{
|
{
|
||||||
if (chunk->size >= size && chunk->is_free)
|
if (heap->size >= size && heap->is_free)
|
||||||
space = chunk_heap(chunk, size);
|
space = chunk_heap(heap, size);
|
||||||
chunk = chunk->next;
|
heap = heap->next;
|
||||||
}
|
}
|
||||||
arena = arena->next;
|
arena = arena->next;
|
||||||
if (!space && arena == &g_base)
|
if (!space && arena == &g_base)
|
||||||
|
|
|
@ -14,5 +14,6 @@
|
||||||
|
|
||||||
void ft_putchar(char c)
|
void ft_putchar(char c)
|
||||||
{
|
{
|
||||||
write(1, &c, 1);
|
if (write(1, &c, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,5 +14,6 @@
|
||||||
|
|
||||||
void ft_putchar_fd(char c, int fd)
|
void ft_putchar_fd(char c, int fd)
|
||||||
{
|
{
|
||||||
write(fd, &c, 1);
|
if (write(fd, &c, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ void ft_putendl(char const *s)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(1, s++, 1);
|
if (write(1, s++, 1) == -1)
|
||||||
write(1, "\n", 1);
|
return ;
|
||||||
|
if (write(1, "\n", 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ void ft_putendl_fd(char const *s, int fd)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(fd, s++, 1);
|
if(write(fd, s++, 1) == -1)
|
||||||
write(fd, "\n", 1);
|
return ;
|
||||||
|
if(write(fd, "\n", 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,6 @@ void ft_putstr(char const *s)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(1, s++, 1);
|
if (write(1, s++, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,6 @@ void ft_putstr_fd(char const *s, int fd)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(fd, s++, 1);
|
if (write(fd, s++, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,57 @@ int inital_base_next_point_to_itself(void)
|
||||||
|
|
||||||
int returns_not_null_pointer(void)
|
int returns_not_null_pointer(void)
|
||||||
{
|
{
|
||||||
void *ptr;
|
t_chunk *ptr;
|
||||||
|
|
||||||
|
g_base.next = &g_base;
|
||||||
ptr = malloc(10);
|
ptr = malloc(10);
|
||||||
_IS(ptr != NULL);
|
_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");
|
_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)
|
int main(void)
|
||||||
{
|
{
|
||||||
_SHOULD(inital_base_next_point_to_itself);
|
_SHOULD(inital_base_next_point_to_itself);
|
||||||
_SHOULD(returns_not_null_pointer);
|
_SHOULD(returns_not_null_pointer);
|
||||||
|
_SHOULD(free_concatenates_andjustent_blocks);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue