diff --git a/include/GDS.h b/include/GDS.h index eb34f23..f7561c5 100644 --- a/include/GDS.h +++ b/include/GDS.h @@ -25,6 +25,7 @@ extern "C" { #include "compare.h" #include "error.h" #include "hash.h" +#include "allocator.h" #ifdef __cplusplus } diff --git a/include/allocator.h b/include/allocator.h new file mode 100644 index 0000000..5145f25 --- /dev/null +++ b/include/allocator.h @@ -0,0 +1,13 @@ +#ifndef __ALLOCATOR_H__ +#define __ALLOCATOR_H__ + +#include + +typedef void* (*malloc_t)(size_t); +typedef void* (*calloc_t)(size_t,size_t); +typedef void* (*realloc_t)(void*,size_t); +typedef void (*free_t)(void*); + +void gds_set_allocator(malloc_t alloc_func, calloc_t calloc_func, realloc_t realloc_func, free_t free_func); + +#endif /* __ALLOCATOR_H__ */ diff --git a/src/avl_tree.c b/src/avl_tree.c index e9293a2..5e65453 100644 --- a/src/avl_tree.c +++ b/src/avl_tree.c @@ -6,7 +6,6 @@ #include "error.h" #include "definitions.h" #include -#include #include // memcpy #include #include @@ -279,10 +278,10 @@ static struct remove_rec_ret remove_rec(AVLNode *node, void *element, comparator AVLNode *aux = node; if (node->left == NULL){ node = node->right; - free(aux); + gdsfree(aux); } else if(node->right == NULL){ node = node->left; - free(aux); + gdsfree(aux); }else { aux = get_max(node->left); memcpy(node->info, aux->info, size); @@ -450,8 +449,8 @@ static struct traversal_ret traversal_rec(AVLNode *node, enum Traversal order, s memcpy(tmp, node->info, size); } cleanup: - free(left.elements); - free(right.elements); + gdsfree(left.elements); + gdsfree(right.elements); return result; } @@ -483,9 +482,9 @@ avl_t* avl_join(const avl_t *tree_1, const avl_t *tree_2){ void *tmp = avl_preorder(tree_1); if (tmp != NULL){ status = avl_add_array(tree_joint, tmp, tree_1->n_elements); - free(tmp); + gdsfree(tmp); if (status != GDS_SUCCESS){ - free(tree_joint); + gdsfree(tree_joint); return NULL; } } @@ -493,9 +492,9 @@ avl_t* avl_join(const avl_t *tree_1, const avl_t *tree_2){ tmp = avl_preorder(tree_2); if (tmp != NULL){ status = avl_add_array(tree_joint, tmp, tree_2->n_elements); - free(tmp); + gdsfree(tmp); if (status != GDS_SUCCESS){ - free(tree_joint); + gdsfree(tree_joint); return NULL; } } @@ -546,13 +545,13 @@ static void free_node(AVLNode *node, destructor_function_t destructor){ destructor(node->info); free_node(node->left, destructor); free_node(node->right, destructor); - free(node); + gdsfree(node); } -static void _avl_free(avl_t *tree){ +static void _avl_gdsfree(avl_t *tree){ if (tree){ free_node(tree->root, tree->destructor); - free(tree); + gdsfree(tree); } } @@ -562,7 +561,7 @@ void (avl_free)(avl_t *t, ...){ va_list arg; va_start(arg, t); do { - _avl_free(t); + _avl_gdsfree(t); t = va_arg(arg, avl_t*); } while (t); va_end(arg); diff --git a/src/gdsmalloc.c b/src/gdsmalloc.c index 18f446c..b96541c 100644 --- a/src/gdsmalloc.c +++ b/src/gdsmalloc.c @@ -1,10 +1,25 @@ #include +#include #include "gdsmalloc.h" #include "error_priv.h" +#include "allocator.h" + +malloc_t __gds_malloc = malloc; +calloc_t __gds_calloc = calloc; +realloc_t __gds_realloc = realloc; +free_t __gds_free = free; + +void gds_set_allocator(malloc_t alloc_func, calloc_t calloc_func, realloc_t realloc_func, free_t free_func) { + __gds_malloc = alloc_func; + __gds_calloc = calloc_func; + __gds_realloc = realloc_func; + __gds_free = free_func; +} + __inline void* gdsmalloc(size_t n) { - void *p = malloc(n); + void *p = __gds_malloc(n); if (!p) register_error(GDS_NOMEM_ERROR); return p; @@ -12,7 +27,7 @@ void* gdsmalloc(size_t n) { __inline void* gdscalloc(size_t nelem, size_t elemsize) { - void *p = calloc(nelem, elemsize); + void *p = __gds_calloc(nelem, elemsize); if (!p) register_error(GDS_NOMEM_ERROR); return p; @@ -20,8 +35,12 @@ void* gdscalloc(size_t nelem, size_t elemsize) { __inline void* gdsrealloc(void *ptr, size_t size) { - void *p = realloc(ptr, size); + void *p = __gds_realloc(ptr, size); if (!p) register_error(GDS_NOMEM_ERROR); return p; } + +__inline void gdsfree(void *ptr) { + __gds_free(ptr); +} diff --git a/src/gdsmalloc.h b/src/gdsmalloc.h index 264e8d7..4f1221b 100644 --- a/src/gdsmalloc.h +++ b/src/gdsmalloc.h @@ -6,5 +6,6 @@ void* gdsmalloc(size_t n); void* gdscalloc(size_t nelem, size_t elemsize); void* gdsrealloc(void *ptr, size_t size); +void gdsfree(void *ptr); #endif /* __XMALLOC_H__ */ diff --git a/src/graph.c b/src/graph.c index c7d545f..208ce16 100644 --- a/src/graph.c +++ b/src/graph.c @@ -34,9 +34,9 @@ static int expand_memory(graph_t *graph, size_t new_size){ float **weights = gdsmalloc(new_size * sizeof(*weights)); int8_t **edges = gdsmalloc(new_size * sizeof(*edges)); if (!vertices || !weights || !edges){ - free(vertices); - free(weights); - free(edges); + gdsfree(vertices); + gdsfree(weights); + gdsfree(edges); return GDS_ERROR; } @@ -49,12 +49,12 @@ static int expand_memory(graph_t *graph, size_t new_size){ if (!weights[i] || !edges[i]){ for (size_t j = 0; j <= i; j++){ - free(weights[j]); - free(edges[j]); + gdsfree(weights[j]); + gdsfree(edges[j]); } - free(vertices); - free(weights); - free(edges); + gdsfree(vertices); + gdsfree(weights); + gdsfree(edges); return GDS_ERROR; } @@ -66,12 +66,12 @@ static int expand_memory(graph_t *graph, size_t new_size){ // Free old pointers for (size_t i = 0; i < graph->max_elements; i++){ - free(graph->weights[i]); - free(graph->edges[i]); + gdsfree(graph->weights[i]); + gdsfree(graph->edges[i]); } - free(graph->vertices); - free(graph->weights); - free(graph->edges); + gdsfree(graph->vertices); + gdsfree(graph->weights); + gdsfree(graph->edges); graph->vertices = vertices; graph->weights = weights; @@ -97,7 +97,7 @@ graph_t* graph_with_capacity(size_t data_size, comparator_function_t cmp, size_t graph->vertices = NULL; graph->data_size = data_size; if (expand_memory(graph, capacity) == GDS_ERROR){ - free(graph); + gdsfree(graph); return NULL; } return graph; @@ -318,8 +318,8 @@ static void graph_init_dijkstra(DijkstraData_t *dijkstra, const graph_t *graph, dijkstra->D = gdsmalloc(graph->n_elements * sizeof(*dijkstra->D)); dijkstra->P = gdsmalloc(graph->n_elements * sizeof(*dijkstra->P)); if (!dijkstra->D || !dijkstra->P){ - free(dijkstra->D); - free(dijkstra->P); + gdsfree(dijkstra->D); + gdsfree(dijkstra->P); dijkstra->status = GDS_ERROR; return; } @@ -373,17 +373,17 @@ DijkstraData_t graph_dijkstra(const graph_t *graph, void *source){ uint8_t *S = calloc(graph->n_elements, sizeof(*S)); if (!S){ - free(dijkstra.D); - free(dijkstra.P); + gdsfree(dijkstra.D); + gdsfree(dijkstra.P); dijkstra.status = GDS_ERROR; return dijkstra; } if ((size_t)source_index >= graph->n_elements){ dijkstra.status = GDS_INDEX_BOUNDS_ERROR; - free(dijkstra.D); - free(dijkstra.P); - free(S); + gdsfree(dijkstra.D); + gdsfree(dijkstra.P); + gdsfree(S); return dijkstra; } @@ -402,13 +402,13 @@ DijkstraData_t graph_dijkstra(const graph_t *graph, void *source){ S[pivot] = 1; pivot = graph_get_pivot(S, dijkstra.D, graph->n_elements); } - free(S); + gdsfree(S); return dijkstra; } void graph_free_dijkstra_data(DijkstraData_t *data){ - free(data->D); - free(data->P); + gdsfree(data->D); + gdsfree(data->P); data->D = NULL; data->P = NULL; } @@ -424,8 +424,8 @@ static void graph_init_floyd(FloydData_t *floyd, const graph_t *graph){ floyd->A = gdsmalloc(sizeof(*floyd->A) * graph->n_elements); floyd->P = gdsmalloc(sizeof(*floyd->P) * graph->n_elements); if (!floyd->A || !floyd->P){ - free(floyd->A); - free(floyd->P); + gdsfree(floyd->A); + gdsfree(floyd->P); floyd->status = GDS_ERROR; return; } @@ -435,11 +435,11 @@ static void graph_init_floyd(FloydData_t *floyd, const graph_t *graph){ floyd->P[i] = gdsmalloc(sizeof(*floyd->P[i]) * graph->n_elements); if (!floyd->A[i] || !floyd->P[i]){ for (size_t j = 0; j <= i; j++){ - free(floyd->A[j]); - free(floyd->P[j]); + gdsfree(floyd->A[j]); + gdsfree(floyd->P[j]); } - free(floyd->A); - free(floyd->P); + gdsfree(floyd->A); + gdsfree(floyd->P); floyd->status = GDS_ERROR; return; } @@ -475,11 +475,11 @@ FloydData_t graph_floyd(const graph_t *graph){ void graph_free_floyd_data(FloydData_t *data){ for (size_t i = 0; i < data->n_elements; i++){ - free(data->A[i]); - free(data->P[i]); + gdsfree(data->A[i]); + gdsfree(data->P[i]); } - free(data->A); - free(data->P); + gdsfree(data->A); + gdsfree(data->P); data->A = NULL; data->P = NULL; } @@ -584,7 +584,7 @@ graph_traversal_t graph_traverse_DF(const graph_t *graph, void *vertex){ uint8_t *visited = calloc(graph->n_elements, sizeof(*visited)); if (!visited){ - free(df.elements); + gdsfree(df.elements); df.elements = NULL; df.status = GDS_ERROR; return df; @@ -592,13 +592,13 @@ graph_traversal_t graph_traverse_DF(const graph_t *graph, void *vertex){ int s = traverse_df_rec(&df, index, visited, graph); if (s != GDS_SUCCESS){ - free(visited); - free(df.elements); + gdsfree(visited); + gdsfree(df.elements); df.status = s; return df; } - free(visited); + gdsfree(visited); return df; } @@ -617,9 +617,9 @@ graph_traversal_t graph_traverse_BF(const graph_t *graph, void *vertex){ uint8_t *visited = calloc(graph->n_elements, sizeof(*visited)); size_t *queue = gdsmalloc(graph->n_elements * sizeof(*queue)); if (!bf.elements || !visited || !queue){ - free(queue); - free(visited); - free(bf.elements); + gdsfree(queue); + gdsfree(visited); + gdsfree(bf.elements); bf.elements = NULL; bf.status = GDS_ERROR; return bf; @@ -651,8 +651,8 @@ graph_traversal_t graph_traverse_BF(const graph_t *graph, void *vertex){ } } } - free(queue); - free(visited); + gdsfree(queue); + gdsfree(visited); return bf; } @@ -668,19 +668,19 @@ static void free_contents(graph_t *graph){ tmp = void_offset(tmp, graph->data_size); } } - free(graph->vertices); + gdsfree(graph->vertices); for (size_t i = 0; i < graph->max_elements; i++){ - free(graph->edges[i]); - free(graph->weights[i]); + gdsfree(graph->edges[i]); + gdsfree(graph->weights[i]); } - free(graph->edges); - free(graph->weights); + gdsfree(graph->edges); + gdsfree(graph->weights); } static void _graph_free(graph_t *graph){ if (graph){ free_contents(graph); - free(graph); + gdsfree(graph); } } diff --git a/src/heap.c b/src/heap.c index 5a60c59..ef6dfcf 100644 --- a/src/heap.c +++ b/src/heap.c @@ -24,7 +24,7 @@ heap_t* heap_init(size_t data_size, comparator_function_t cmp){ if (!heap) return NULL; heap->elements = vector_init(data_size, cmp); if (!heap->elements){ - free(heap); + gdsfree(heap); return NULL; } return heap; @@ -236,7 +236,7 @@ bool heap_isempty(const heap_t *heap){ static void _heap_free(heap_t *heap){ if (heap){ vector_free(heap->elements); - free(heap); + gdsfree(heap); } } diff --git a/src/linked_list.c b/src/linked_list.c index 59745ca..742b7a3 100644 --- a/src/linked_list.c +++ b/src/linked_list.c @@ -176,7 +176,7 @@ void* list_get_array(const linked_list_t *list, size_t array_length){ void *array = gdsmalloc(list->data_size * array_length); assert(array); if (!list_get_into_array(list, array, array_length)){ - free(array); + gdsfree(array); return NULL; } return array; @@ -203,7 +203,7 @@ int list_remove(linked_list_t *list, void *element){ if (list->destructor) list->destructor(tmp->info); - free(tmp); + gdsfree(tmp); list->n_elements--; return GDS_SUCCESS; } @@ -222,7 +222,7 @@ int list_remove_front(linked_list_t *list){ list->head = list->head->next; if (list->destructor) list->destructor(del->info); - free(del); + gdsfree(del); list->n_elements--; return GDS_SUCCESS; } @@ -237,7 +237,7 @@ int list_remove_back(linked_list_t *list){ list->tail = list->tail->prev; if (list->destructor) list->destructor(del->info); - free(del); + gdsfree(del); list->n_elements--; return GDS_SUCCESS; } @@ -268,7 +268,7 @@ void* list_pop(linked_list_t *list, void *element, void *dest){ if (dest) memcpy(dest, tmp->info, list->data_size); - free(tmp); + gdsfree(tmp); list->n_elements--; return dest; } @@ -287,7 +287,7 @@ void* list_pop_front(linked_list_t *list, void *dest){ list->head = list->head->next; if (dest) memcpy(dest, del->info, list->data_size); - free(del); + gdsfree(del); list->n_elements--; return dest; } @@ -302,7 +302,7 @@ void* list_pop_back(linked_list_t *list, void *dest){ list->tail = list->tail->prev; if (dest) memcpy(dest, del->info, list->data_size); - free(del); + gdsfree(del); list->n_elements--; return dest; } @@ -370,13 +370,13 @@ static void list_free_node(LLNode *node, destructor_function_t destructor){ if (destructor) destructor(node->info); list_free_node(node->next, destructor); - free(node); + gdsfree(node); } static void _list_free(linked_list_t *list){ if (list){ list_free_node(list->head, list->destructor); - free(list); + gdsfree(list); } } diff --git a/src/queue.c b/src/queue.c index 0950703..3c8f20a 100644 --- a/src/queue.c +++ b/src/queue.c @@ -101,7 +101,7 @@ void* queue_dequeue(queue_t *queue, void *dest){ queue_tNode *aux = queue->head; queue->head = queue->head->next; memcpy(dest, aux->info, queue->data_size); - free(aux); + gdsfree(aux); queue->n_elements--; return dest; } @@ -148,7 +148,7 @@ int queue_remove(queue_t *queue, void *element){ return GDS_ELEMENT_NOT_FOUND_ERROR; queue_tNode *del = *aux; *aux = (*aux)->next; - free(del); + gdsfree(del); queue->n_elements--; return GDS_SUCCESS; } @@ -171,13 +171,13 @@ static void queue_free_node(queue_tNode *node, destructor_function_t destructor) if (destructor) destructor(node->info); queue_free_node(node->next, destructor); - free(node); + gdsfree(node); } static void _queue_free(queue_t *queue){ if (queue){ queue_free_node(queue->head, queue->destructor); - free(queue); + gdsfree(queue); } } diff --git a/src/stack.c b/src/stack.c index 83b4d37..4322905 100644 --- a/src/stack.c +++ b/src/stack.c @@ -23,7 +23,7 @@ stack_t* stack_init(size_t data_size, comparator_function_t cmp){ if (!stack) return NULL; stack->elements = vector_init(data_size,cmp); if (!stack->elements){ - free(stack); + gdsfree(stack); return NULL; } return stack; @@ -102,7 +102,7 @@ bool stack_isempty(const stack_t *stack){ static void _stack_free(stack_t *stack){ if (stack){ vector_free(stack->elements); - free(stack); + gdsfree(stack); } } diff --git a/src/vector.c b/src/vector.c index 0d6204d..3c9075b 100644 --- a/src/vector.c +++ b/src/vector.c @@ -43,7 +43,7 @@ vector_t* vector_with_capacity(size_t data_size, comparator_function_t cmp, size if (!vector) return NULL; vector->elements = gdsmalloc(capacity * data_size); if (!vector->elements){ - free(vector); + gdsfree(vector); return NULL; } vector->data_size = data_size; @@ -462,7 +462,7 @@ void* vector_get_array(const vector_t *vector, size_t array_length){ return NULL; } if (!vector_get_into_array(vector, array, array_length)){ - free(array); + gdsfree(array); return NULL; } return array; @@ -479,17 +479,16 @@ int vector_swap(vector_t *vector, ptrdiff_t index_1, ptrdiff_t index_2){ return status; void *tmp = gdsmalloc(vector->data_size); if (!tmp || !vector_at(vector, index_1, tmp)){ - free(tmp); + gdsfree(tmp); return GDS_ERROR; } void *e1 = void_offset(vector->elements, index_1 * vector->data_size); void *e2 = void_offset(vector->elements, index_2 * vector->data_size); - assert(e1 && e2); memmove(e1, e2, vector->data_size); memcpy(e2, tmp, vector->data_size); - free(tmp); + gdsfree(tmp); return GDS_SUCCESS; } @@ -604,8 +603,8 @@ static void _vector_free(vector_t *vector){ if (!vector) return; destroy_content(vector); - free(vector->elements); - free(vector); + gdsfree(vector->elements); + gdsfree(vector); } void (vector_free)(vector_t *v, ...){ @@ -624,7 +623,7 @@ void vector_reset(vector_t *vector){ if (!vector) return; destroy_content(vector); - free(vector->elements); + gdsfree(vector->elements); vector->elements = gdsmalloc(VECTOR_DEFAULT_SIZE * vector->data_size); assert(vector->elements); vector->n_elements = 0;