Skip to content

Commit

Permalink
Add function to set custom allocators
Browse files Browse the repository at this point in the history
  • Loading branch information
saulvaldelvira committed Sep 24, 2024
1 parent a7df25d commit 202eb5d
Show file tree
Hide file tree
Showing 11 changed files with 122 additions and 90 deletions.
1 change: 1 addition & 0 deletions include/GDS.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extern "C" {
#include "compare.h"
#include "error.h"
#include "hash.h"
#include "allocator.h"

#ifdef __cplusplus
}
Expand Down
13 changes: 13 additions & 0 deletions include/allocator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef __ALLOCATOR_H__
#define __ALLOCATOR_H__

#include <stddef.h>

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__ */
25 changes: 12 additions & 13 deletions src/avl_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "error.h"
#include "definitions.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h> // memcpy
#include <stdarg.h>
#include <assert.h>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -483,19 +482,19 @@ 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;
}
}

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;
}
}
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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);
Expand Down
25 changes: 22 additions & 3 deletions src/gdsmalloc.c
Original file line number Diff line number Diff line change
@@ -1,27 +1,46 @@
#include <stdlib.h>
#include <stdint.h>
#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;
}

__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;
}

__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);
}
1 change: 1 addition & 0 deletions src/gdsmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
98 changes: 49 additions & 49 deletions src/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -584,21 +584,21 @@ 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;
}

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;
}

Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand All @@ -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);
}
}

Expand Down
Loading

0 comments on commit 202eb5d

Please sign in to comment.