diff options
author | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-04-19 02:45:29 -0300 |
---|---|---|
committer | Rafael G. Martins <rafael@rafaelmartins.eng.br> | 2015-04-19 02:45:29 -0300 |
commit | 8f4cba86a56cd69d95b07dda7e002f33cbe6ba62 (patch) | |
tree | 9e25ebf9043a0dc70dd721f3b20704fa572b9674 | |
parent | 1826b5ad70ebd5db751ed0d4eee6f857a7001100 (diff) | |
download | blogc-8f4cba86a56cd69d95b07dda7e002f33cbe6ba62.tar.gz blogc-8f4cba86a56cd69d95b07dda7e002f33cbe6ba62.tar.bz2 blogc-8f4cba86a56cd69d95b07dda7e002f33cbe6ba62.zip |
trie: fixed memory leak when replacing existing key
-rw-r--r-- | src/utils/trie.c | 5 | ||||
-rw-r--r-- | tests/check_utils.c | 34 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/utils/trie.c b/src/utils/trie.c index f1b77eb..e0ac1af 100644 --- a/src/utils/trie.c +++ b/src/utils/trie.c @@ -82,8 +82,9 @@ b_trie_insert(b_trie_t *trie, const char *key, void *data) parent = tmp; - if (previous == NULL || parent != NULL) + if (previous == NULL || parent != NULL) { goto clean; + } current = b_malloc(sizeof(b_trie_node_t)); current->key = *key; @@ -95,6 +96,8 @@ b_trie_insert(b_trie_t *trie, const char *key, void *data) clean: if (*key == '\0') { + if (parent->data != NULL && trie->free_func != NULL) + trie->free_func(parent->data); parent->data = data; break; } diff --git a/tests/check_utils.c b/tests/check_utils.c index 5f4cb9f..b3bada7 100644 --- a/tests/check_utils.c +++ b/tests/check_utils.c @@ -623,6 +623,39 @@ test_trie_insert(void **state) static void +test_trie_insert_duplicated(void **state) +{ + b_trie_t *trie = b_trie_new(free); + + b_trie_insert(trie, "bola", b_strdup("guda")); + assert_true(trie->root->key == 'b'); + assert_null(trie->root->data); + assert_true(trie->root->child->key == 'o'); + assert_null(trie->root->child->data); + assert_true(trie->root->child->child->key == 'l'); + assert_null(trie->root->child->child->data); + assert_true(trie->root->child->child->child->key == 'a'); + assert_null(trie->root->child->child->child->data); + assert_true(trie->root->child->child->child->child->key == '\0'); + assert_string_equal(trie->root->child->child->child->child->data, "guda"); + + b_trie_insert(trie, "bola", b_strdup("asdf")); + assert_true(trie->root->key == 'b'); + assert_null(trie->root->data); + assert_true(trie->root->child->key == 'o'); + assert_null(trie->root->child->data); + assert_true(trie->root->child->child->key == 'l'); + assert_null(trie->root->child->child->data); + assert_true(trie->root->child->child->child->key == 'a'); + assert_null(trie->root->child->child->child->data); + assert_true(trie->root->child->child->child->child->key == '\0'); + assert_string_equal(trie->root->child->child->child->child->data, "asdf"); + + b_trie_free(trie); +} + + +static void test_trie_keep_data(void **state) { b_trie_t *trie = b_trie_new(NULL); @@ -781,6 +814,7 @@ main(void) // trie unit_test(test_trie_new), unit_test(test_trie_insert), + unit_test(test_trie_insert_duplicated), unit_test(test_trie_keep_data), unit_test(test_trie_lookup), unit_test(test_trie_size), |