From 1cf3c5d35406e424f52903e37cb5b7b0877512e7 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 4 Feb 2011 03:17:39 +0000 Subject: Fix memory leaks. git-svn-id: http://svn.drobilla.net/sord/trunk@18 3d64ff67-21c5-427c-a301-fe4f08042e5a --- src/sord.c | 86 +++++++++++++++++++++++++++++++++++------------------------- src/syntax.c | 12 ++++++--- 2 files changed, 58 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/sord.c b/src/sord.c index d14cebb..3e98095 100644 --- a/src/sord.c +++ b/src/sord.c @@ -537,8 +537,9 @@ Sord sord_new() { Sord sord = (Sord)malloc(sizeof(struct _Sord)); - sord->names = g_hash_table_new_full(g_str_hash, g_str_equal, 0, 0); + sord->names = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0); sord->literals = g_hash_table_new_full(sord_literal_hash, sord_literal_equal, 0, 0); + sord->user_data_free = NULL; for (unsigned i = 0; i < NUM_ORDERS; ++i) @@ -547,12 +548,51 @@ sord_new() return sord; } +static void +sord_add_tuple_ref(Sord sord, const SordID id) +{ + if (id) { + SordNode node = sord_node_load(sord, id); + ++node->refs; + } +} + +static void +sord_drop_node(Sord sord, SordID id) +{ + SordNode node = sord_node_load(sord, id); + free(node->buf); + free(node); +} + +static void +sord_drop_tuple_ref(Sord sord, const SordID id) +{ + if (id) { + SordNode node = sord_node_load(sord, id); + if (--node->refs == 0) { + sord_drop_node(sord, id); + } + } +} + void sord_free(Sord sord) { if (!sord) return; + // Free nodes + SordTuple tup; + SordIter i = sord_begin(sord); + for (; !sord_iter_end(i); sord_iter_next(i)) { + sord_iter_get(i, tup); + for (int i = 0; i < TUP_LEN; ++i) { + sord_drop_tuple_ref(sord, tup[i]); + } + } + sord_iter_free(i); + g_hash_table_unref(sord->names); g_hash_table_unref(sord->literals); for (unsigned i = 0; i < NUM_ORDERS; ++i) @@ -577,12 +617,12 @@ sord_set_option(Sord sord, const char* key, const char* value, const bool value_is_true = !strcmp(value, "true") || !strcmp(value, "1") || !strcmp(value, "yes"); if (!strcmp(option, "index-all")) { for (int i = 0; i < NUM_ORDERS; ++i) { - sord->indices[i] = g_sequence_new(NULL); + sord->indices[i] = g_sequence_new(free); } } else if (!strncmp(option, "index-", 6) && value_is_true) { for (int i = 0; i < NUM_ORDERS; ++i) { if (!strcmp(option + 6, order_names[i])) { - sord->indices[i] = g_sequence_new(NULL); + sord->indices[i] = g_sequence_new(free); return; } } @@ -605,12 +645,11 @@ sord_open(Sord sord) } if (no_indices) { - // Use default indexing, avoids O(n) in all cases - sord->indices[SPO] = g_sequence_new(NULL); - sord->indices[OPS] = g_sequence_new(NULL); - //sord->indices[PSO] = g_sequence_new(NULL); - sord->indices[GSPO] = g_sequence_new(NULL); // XXX: default? do on demand? - sord->indices[GOPS] = g_sequence_new(NULL); // XXX: default? do on demand? + // FIXME: make sord_new take a parameter so this is explicit + sord->indices[SPO] = g_sequence_new(free); + sord->indices[OPS] = g_sequence_new(free); + sord->indices[GSPO] = g_sequence_new(free); + sord->indices[GOPS] = g_sequence_new(free); } if (!sord->indices[DEFAULT_ORDER]) @@ -619,12 +658,6 @@ sord_open(Sord sord) return true; } -static void -sord_drop_node(Sord sord, SordID id) -{ - // FIXME: leak? -} - int sord_num_tuples(Sord sord) { @@ -926,26 +959,6 @@ sord_get_literal(Sord sord, bool create, SordID type, const char* str, const cha lang, lang ? strlen(lang) : 0); } -static void -sord_add_tuple_ref(Sord sord, const SordID id) -{ - if (id) { - SordNode node = sord_node_load(sord, id); - ++node->refs; - } -} - -static void -sord_drop_tuple_ref(Sord sord, const SordID id) -{ - if (id) { - SordNode node = sord_node_load(sord, id); - if (--node->refs == 0) { - sord_drop_node(sord, id); - } - } -} - static inline bool sord_add_to_index(Sord sord, const SordTuple tup, SordOrder order) { @@ -960,7 +973,8 @@ sord_add_to_index(Sord sord, const SordTuple tup, SordOrder order) return false; // Tuple already stored in this index } - // FIXME: memory leak? + // FIXME: would be nice to share tuples and just use a different comparator + // for each index (save significant space overhead per tuple) SordID* key_copy = malloc(sizeof(SordTuple)); memcpy(key_copy, key, sizeof(SordTuple)); g_sequence_insert_before(cur, key_copy); diff --git a/src/syntax.c b/src/syntax.c index ac1a766..e7560c5 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -114,7 +114,9 @@ sord_node_from_serd_node(ReadState* state, const SerdNode* sn) } SerdURI ignored; SerdNode abs_uri_node = serd_node_new_uri(&abs_uri, &ignored); - return sord_get_uri(state->sord, true, (const char*)abs_uri_node.buf); + SordID ret = sord_get_uri(state->sord, true, (const char*)abs_uri_node.buf); + serd_node_free(&abs_uri_node); + return ret; } case SERD_CURIE: { SerdChunk uri_prefix; @@ -124,12 +126,14 @@ sord_node_from_serd_node(ReadState* state, const SerdNode* sn) return NULL; } const size_t uri_len = uri_prefix.len + uri_suffix.len; - char* buf = malloc(uri_len + 1); + char* buf = malloc(uri_len + 1); memcpy(buf, uri_prefix.buf, uri_prefix.len); memcpy(buf + uri_prefix.len, uri_suffix.buf, uri_suffix.len); buf[uri_len] = '\0'; - return sord_get_uri_counted(state->sord, true, - buf, uri_prefix.len + uri_suffix.len); + SordID ret = sord_get_uri_counted(state->sord, true, + buf, uri_prefix.len + uri_suffix.len); + free(buf); + return ret; } case SERD_BLANK_ID: case SERD_ANON_BEGIN: -- cgit v1.2.1