259 lines
5.9 KiB
C
259 lines
5.9 KiB
C
/*
|
|
Copyright (c) 2018 Muresan Vlad Mihail
|
|
Contact Info muresanvladmihail@gmail.com, murii@tilde.team
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software.
|
|
Shall you use this software in a product, an acknowledgment and the
|
|
contact info(if there is any) of the author(s) must be placed in
|
|
the product documentation.
|
|
2. This notice may not be removed or altered from any source distribution.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
|
|
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
|
|
AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE
|
|
BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*/
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include "vector.h"
|
|
|
|
#include "mlc.h"
|
|
|
|
typedef struct {
|
|
const char* file; /* file in which the allocation happened */
|
|
size_t line; /* line at which the allocation happened */
|
|
size_t size; /* the size of allocated object */
|
|
char free; /* 1-> free, 0-> not free yet */
|
|
void* ptr; /* the actual object which is allocated */
|
|
} alloc_struct;
|
|
|
|
|
|
static vec_t* elements_v; /* holds all allocated structures */
|
|
|
|
|
|
void mlc_init()
|
|
{
|
|
elements_v = vec_init(sizeof(void*));
|
|
}
|
|
|
|
|
|
void mlc_destroy()
|
|
{
|
|
vec_destroy(elements_v);
|
|
}
|
|
|
|
|
|
static void add_structure(void* ptr, size_t obj_size, const char* file, unsigned line)
|
|
{
|
|
alloc_struct* ns = malloc(sizeof(alloc_struct));
|
|
if (!ns)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_ERRORS
|
|
fprintf(stderr, "Couldn't allocate mlc structure: %s, line %u\n", file, line);
|
|
#endif
|
|
return;
|
|
}
|
|
ns->file = file;
|
|
ns->line = line;
|
|
ns->size = obj_size;
|
|
ns->ptr = ptr;
|
|
ns->free = 0;
|
|
|
|
vec_append(elements_v, ns);
|
|
}
|
|
|
|
|
|
static long has_structure(void* ptr)
|
|
{
|
|
size_t i = 0;
|
|
while (i < vec_size(elements_v))
|
|
{
|
|
alloc_struct *str = (alloc_struct*)vec_get(elements_v, i);
|
|
if (str->ptr == ptr)
|
|
return i;
|
|
i++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
void* _mlc_malloc(size_t size, const char* file, unsigned line)
|
|
{
|
|
void* ptr = malloc(size);
|
|
if (!ptr)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_ERRORS
|
|
fprintf(stderr, "Couldn't allocate: %s, line %u\n", file, line);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
#ifdef MLC_ACT_NORMAL
|
|
return ptr;
|
|
#endif
|
|
add_structure(ptr, size, file, line);
|
|
return ptr;
|
|
}
|
|
|
|
|
|
void* _mlc_calloc(size_t nitems, size_t size, const char* file, unsigned line)
|
|
{
|
|
void* ptr = calloc(nitems, size);
|
|
if (!ptr)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_ERRORS
|
|
fprintf(stderr, "Couldn't allocate: %s, line %u\n", file, line);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
#ifdef MLC_ACT_NORMAL
|
|
return ptr;
|
|
#endif
|
|
add_structure(ptr, size, file, line);
|
|
return ptr;
|
|
}
|
|
|
|
|
|
void* _mlc_realloc(void* ptr, size_t size, const char* file, unsigned line)
|
|
{
|
|
#ifdef MLC_ACT_NORMAL
|
|
void* _ptr = realloc(ptr, size);
|
|
if (!_ptr)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_ERRORS
|
|
fprintf(stderr, "Couldn't reallocate: %s, line %u\n", file, line);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
return _ptr;
|
|
#endif
|
|
|
|
void* _ptr = realloc(ptr, size);
|
|
alloc_struct* as = NULL;
|
|
size_t index = 0;
|
|
if (!_ptr)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_ERRORS
|
|
fprintf(stderr, "Couldn't reallocate: %s, line %u\n", file, line);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
index = has_structure(ptr);
|
|
as = (alloc_struct*)vec_get(elements_v, index);
|
|
|
|
if (!as)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_WARNINGS
|
|
fprintf(stdout, "Reallocating is happening on a NULL ptr %s %u\n", file, line);
|
|
#endif
|
|
add_structure(_ptr, size, file, line);
|
|
}
|
|
else
|
|
{
|
|
as->ptr = _ptr;
|
|
as->size = size;
|
|
}
|
|
return _ptr;
|
|
}
|
|
|
|
|
|
void _mlc_free(void* ptr, const char* file, unsigned line)
|
|
{
|
|
#ifdef MLC_ACT_NORMAL
|
|
free(ptr);
|
|
#endif
|
|
alloc_struct* as = NULL;
|
|
size_t index = 0;
|
|
if (ptr == NULL)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_WARNINGS
|
|
fprintf(stderr, "Couldn't free object: %s, line %u %s \n", file, line, " because it's NULL");
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
|
|
index = has_structure(ptr);
|
|
if (index < 0)
|
|
return;
|
|
as = (alloc_struct*)vec_get(elements_v, index);
|
|
if (!as)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_WARNINGS
|
|
fprintf(stderr, "Invalid free: %s, line %u\n", file, line);
|
|
#endif
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
as->free = 1;
|
|
}
|
|
free(ptr);
|
|
ptr = NULL;
|
|
}
|
|
|
|
|
|
size_t _mlc_size(void* ptr, const char* file, unsigned line)
|
|
{
|
|
alloc_struct* _ptr = (alloc_struct*)vec_get(elements_v, has_structure(ptr));
|
|
if (!ptr)
|
|
{
|
|
#ifdef MLC_CHECK_FOR_WARNINGS
|
|
fprintf(stderr, "Bad pointer: %s, line %u\n", file, line);
|
|
#endif
|
|
return -1;
|
|
}
|
|
return _ptr->size;
|
|
}
|
|
|
|
|
|
size_t mlc_usage()
|
|
{
|
|
#ifdef MLC_ACT_NORMAL
|
|
return 0;
|
|
#endif
|
|
size_t usage = 0;
|
|
size_t i = 0;
|
|
while (i < vec_size(elements_v))
|
|
{
|
|
alloc_struct* ptr = ((alloc_struct*)vec_get(elements_v, i));
|
|
if (ptr->free == 0)
|
|
usage += ptr->size;
|
|
i++;
|
|
}
|
|
return usage;
|
|
}
|
|
|
|
|
|
void mlc_dump(FILE* file)
|
|
{
|
|
#ifdef MLC_ACT_NORMAL
|
|
return;
|
|
#endif
|
|
alloc_struct* curr = NULL;
|
|
size_t i = 0;
|
|
size_t size = vec_size(elements_v);
|
|
|
|
if (!file)
|
|
file = stdout;
|
|
|
|
if (size == 0)
|
|
fprintf(file, "MLC: no memory leaks! \n");
|
|
|
|
while (i < size)
|
|
{
|
|
curr = vec_get(elements_v, i);
|
|
if (curr->free == 0)
|
|
fprintf(file, "MLC: Unfreed: %p %s, line %zu\n", curr->ptr, curr->file, curr->line);
|
|
i++;
|
|
}
|
|
}
|
|
|