-
Notifications
You must be signed in to change notification settings - Fork 0
Memory manager
This is the header with API: ft_memory_manager.h and this is the implementation folder: sources/ft_memman/
Special for memory manager I wrote a simple error handler. But now, it's independent part of library, so you can use it, when it convenient.
Check ft_error.h and ft_error.c
void ft_error_print(const char *msg)
Just write msg
to FD_STDERR (from libft.h) previously pushing a output buffer.
You may not immediately realize, but it's very useful to not
#include <unistd.h>
, writeft_strlen()
, push buffer by hands and etc. when you wona just print error, but thats true!
void ft_error_exit(const char *msg, int exit_code)
This func do the same but also it call exit(exit_code)
(and abort you app, obviously!).
void ft_error_free_exit(const char *msg, int exit_code)
This func do the same but also it call ft_memman_clean()
(free()
all memmory allocated by malloc()
) before exit(exit_code)
.
This function must be called at the beginning of program. Inside the memory manager uses a static dynamic array. It's just a simple repository for storing every pointer to the memory that has been allocated. But, since this is a dynamic array (allocate memory until RAM runs out), it also requires initialization, allocating memory for itself. In case malloc()
inside this func return NULL
, ft_error_exit(ERR_MEMALLOC_MSG, MEMERR_CODE)
will be called!
MEMERR_CODE
defined inft_memory_manager.h
(0
by default). If you want your application to return NOT0
in case of a memory allocation failure, change it!
This function must be called at the end of program (or before exit()
). It iterates over all stored pointers and free()
them. After it free memory under himself. So, if you are not a fool, all allocated memory will be guaranteed to be freed!
WATCH OUT!!! This mechanic is designed to conveniently handle errors and create easy, beautiful and readable code! If you use it to remove
memory leaks
(causevalgrind
will not show you anything) then your program still has leaks! DO NOT CHEAT!!!
To check on leaks put breakpoint in debuger at
ft_memman_clean()
(or comment out cycle inside)!
You should use these functions instead standard! Really, with my library there is no reason to use malloc() realloc() and free()
Even if you turn off memory manager, you have no need to change
ft_malloc()
tomalloc()
! Check malloc.c!
All you need to know is that either ft_malloc()
and ft_remalloc()
will allocate memory for you, or they will call ft_error_free_exit(ERR_MEMALLOC_MSG, MEMERR_CODE)
! And ft_free()
either free()
the requested memory, or prints an error message (if this memory was not allocated) and returns control to the program (not fault like standard).
No, all functions will be work correct. Check memory manager sources to find answer.
#define |
Description |
---|---|
# define INIT_MM_SIZE 128 |
Under how many pointers the memory will be allocated during initialization. |
# define MM_MAX_INCREMENT 1024 |
Maximum step to increase memory manager size |
# define MM_DIFF_FOR_TRIM 64 |
If after ft_free() curlen of mem_manager < max_size / 2 - MM_DIFF_FOR_TRIM mem_manager size will be halved |
Let me show you how convenient it is!
Let's write a function that creates a two-dimensional array (simple matrix).
- Without my library
void delete_matrix(int **matrix, size_t rows)
{
for (size_t i = 0; i < rows; i++)
free(matrix[i]);
free(matrix);
}
int **init_matrix(size_t rows, size_t cols)
{
int **result;
result = malloc(sizeof(int *) * rows);
if (result == NULL)
return (NULL);
for (size_t i = 0; i < rows; i++)
{
result[i] = malloc(sizeof(int) * cols);
if (result[i] == NULL)
{
delete_matrix(result, i);
return (NULL);
}
}
return (result);
}
int main(void)
{
int **matrix;
matrix = init_matrix(10, 10);
if (matrix == NULL)
{
ft_printf("Error!");
return (0);
}
ft_printf("OK!");
delete_matrix(matrix, 10);
return (0);
}
- With using my library
void delete_matrix(int **matrix, size_t rows)
{
for (size_t i = 0; i < rows; i++)
ft_free(matrix[i]);
ft_free(matrix);
}
int **init_matrix(size_t rows, size_t cols)
{
int **result;
result = ft_malloc(sizeof(int *) * rows);
for (size_t i = 0; i < rows; i++)
result[i] = ft_malloc(sizeof(int) * cols);
return (result);
}
int main(void)
{
int **matrix;
ft_memman_init();
matrix = init_matrix(10, 10);
ft_printf("OK!");
delete_matrix(matrix, 10);
ft_memman_clean();
return (0);
}
In my version, main()
is 5 lines shorter, and init_matrix()
is 9 lines shorter! And my code is MUCH more readable and more beautiful!
Now imagine that you are develop a large project with a large level of nesting functions! If you still think that there is no need for my memory manager, I have no reason to talk to you!