Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <unistd.h>
- #include <errno.h>
- #include <string.h>
- #include "./include/my_malloc.h"
- metadata_t *head = NULL;
- struct chunk {
- struct chunk *next, *prev;
- size_t size;
- int free;
- void *data;
- };
- void my_putchar(char c)
- {
- write(1, &c, 1);
- }
- typedef struct chunk *Chunk;
- void my_putnbr(int nb)
- {
- int debut;
- int fin;
- if (nb < 0) {
- my_putchar('-');
- my_putnbr(-nb);
- } else {
- fin = nb % 10;
- debut = nb / 10;
- if (debut != 0)
- my_putnbr(debut);
- my_putchar(fin + '0');
- }
- }
- int put_adress(unsigned long nb)
- {
- int to_print;
- int base;
- char *str = "0123456789";
- base = strlen(str);
- if (nb >= base) {
- to_print = nb % base;
- nb = (nb - to_print) / base;
- put_adress(nb);
- my_putchar(str[to_print]);
- } else
- my_putchar(str[nb]);
- return (0);
- }
- static void *malloc_base() {
- /*static Chunk b = NULL;
- if (!b) {
- b = sbrk(word_align(sizeof(struct chunk)));
- if (b == (void*) -1) {
- _exit(127);
- }
- b->next = NULL;
- b->prev = NULL;
- b->size = 0;
- b->free = 0;
- b->data = NULL;
- }
- return b;*/
- }
- metadata_t *find_block(size_t size, metadata_t **old)
- {
- metadata_t *tmp = head;
- while (tmp) {
- void *tmppp = sbrk(0);
- put_adress((long int)tmppp);
- write(1, "\n", 1);
- put_adress((long int)tmp);
- write(1, "\n", 1);
- my_putnbr(tmp->size);
- my_putnbr(tmp->free);
- write(1, "step01\n", 7);
- if (tmp->free && tmp->size > size) {
- write(1, "step04\n", 7);
- return tmp;
- }
- write(1, "step02\n", 7);
- *old = tmp;
- write(1, "step03\n", 7);
- tmp = tmp->next;
- }
- return NULL;
- }
- void malloc_merge_next(Chunk c) {
- c->size = c->size + c->next->size + sizeof(struct chunk);
- c->next = c->next->next;
- if (c->next) {
- c->next->prev = c;
- }
- }
- size_t get_size_to_alloc(size_t raw_size)
- {
- size_t amount = 0;
- while (amount <= raw_size) {
- amount += getpagesize();
- }
- amount += (getpagesize() * 10);
- return amount;
- }
- void split_block(metadata_t *first, size_t size)
- {
- metadata_t *second = (metadata_t*)((char*) first
- + size + sizeof(metadata_t));
- second->next = first->next;
- first->next = second;
- if (second->next)
- second->next->prev = second;
- second->size = first->size - (size + sizeof(metadata_t));
- first->size = size;
- second->free = 1;
- second->prev = first;
- second->data = second + 1;
- }
- void *alloc_first(size_t size)
- {
- size_t raw_size = size + sizeof(metadata_t);
- size_t to_alloc = get_size_to_alloc(raw_size);
- head = sbrk(0);
- if (sbrk(to_alloc) == (void*) -1)
- return NULL;
- head->size = to_alloc - sizeof(metadata_t);
- head->next = NULL;
- head->data = head + 1;
- head->prev = NULL;
- head->free = 0;
- split_block(head, size);
- put_adress((long int)head);
- write(1, "===\n", 4);
- put_adress((long int)head->next);
- write(1, "\n===\n", 5);
- return head;
- }
- void *append_new_blocks(metadata_t *last, size_t size)
- {
- size_t raw_size = size + sizeof(metadata_t);
- size_t to_alloc = get_size_to_alloc(raw_size);
- metadata_t *new;
- new = sbrk(0);
- if (sbrk(to_alloc) == (void*) -1)
- return NULL;
- new->data = new + 1;
- new->prev = last;
- new->free = 0;
- new->next = NULL;
- new->size = to_alloc - sizeof(metadata_t);
- last->next = new;
- split_block(new, size);
- return new;
- }
- void *fill_block(metadata_t *to_fill, size_t size)
- {
- write(1, "fill\n", 5);
- to_fill->free = 0;
- if (to_fill->size > size + sizeof(metadata_t))
- split_block(to_fill, size);
- return to_fill;
- }
- void *malloc(size_t size)
- {
- metadata_t *prev;
- metadata_t *tmp;
- my_putnbr(size);
- write(1, "\n", 1);
- if (!size)
- return NULL;
- if (!head)
- return alloc_first(size);
- put_adress((long int)head);
- write(1, "===\n", 4);
- put_adress((long int)head->next);
- write(1, "\n===\n", 5);
- write(1, "step1\n", 6);
- tmp = find_block(size, &prev);
- write(1, "step2\n", 6);
- if (!tmp) {
- write(1, "step3\n", 6);
- return append_new_blocks(prev, size);
- } else {
- write(1, "step4\n", 6);
- return fill_block(tmp, size);
- }
- }
- void free(void *ptr) {
- return;
- if (!ptr || ptr < malloc_base() || ptr > sbrk(0)) return;
- Chunk c = (Chunk) ptr - 1;
- if (c->data != ptr) return;
- c->free = 1;
- if (c->next && c->next->free) {
- malloc_merge_next(c);
- }
- if (c->prev->free) {
- malloc_merge_next(c = c->prev);
- }
- if (!c->next) {
- c->prev->next = NULL;
- sbrk(- c->size - sizeof(struct chunk));
- }
- }
- /*
- void *calloc(size_t nmemb, size_t size) {
- return NULL;
- size_t length = nmemb * size;
- void *ptr = malloc(length);
- if (ptr) {
- char *dst = ptr;
- for (size_t i = 0; i < length; *dst = 0, ++dst, ++i);
- }
- return ptr;
- }
- void *realloc(void *ptr, size_t size) {
- return NULL;
- void *newptr = malloc(size);
- if (newptr && ptr && ptr >= malloc_base() && ptr <= sbrk(0)) {
- Chunk c = (Chunk) ptr - 1;
- if (c->data == ptr) {
- size_t length = c->size > size ? size : c->size;
- char *dst = newptr, *src = ptr;
- for (size_t i = 0; i < length; *dst = *src, ++src, ++dst, ++i);
- free(ptr);
- }
- }
- return newptr;
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement