Reputation: 869
Having populated a POSIX binary tree with tsearch
, how is it possible to clean-up the entire tree? GCC provides tdestroy
as an extension, but if you want to use POSIX-only functions how can you do it?
My current implementation uses twalk
to walk the tree and, for endorder
and leaf
nodes, calls tdelete
, but this understandably shows warnings about const-correctness:
static void free_tree(const void *node, const VISIT which, const int depth)
{
struct search_entry *entry;
switch (which) {
case endorder:
case leaf:
entry = *(struct search_entry **)node;
tdelete(entry->key, &node, search_entry_compare);
free(entry);
}
}
What was the expected approach for POSIX-compliant applications?
Upvotes: 3
Views: 388
Reputation: 753675
The POSIX description of the tsearch()
family of functions has an informative Examples section which shows how the standard thinks you can delete all the elements of a tree (as part of a bigger, complete example of how to use the functions):
/* Delete all nodes in the tree */ while (root != NULL) { elementptr = *(struct element **)root; printf("deleting node: string = %s, count = %d\n", elementptr->string, elementptr->count); tdelete((void *)elementptr, &root, delete_root); free(elementptr); }
Basically, it repeatedly deletes the root node with tdelete()
until there is no longer a root node to delete. The delete_root()
function is also shown — it is a no-op that returns 0 for success.
We can debate the merits (or lack of them) for the cast in the call to tdelete()
.
Upvotes: 6
Reputation: 11232
The proposed solution of calling tdelete()
from twalk()
's action
conflicts with the POSIX requirement on the application that action
and compar
not change the tree. In practice, a use after free or incomplete cleanup is likely.
The best I can think of is either not using tsearch/tfind/tdelete/twalk or allocating new memory to store twalk()
results and using tdelete()
afterwards.
Not using tsearch/tfind/tdelete/twalk may also allow data structures such as radix tries and hash tables that tend to be more efficient on modern architectures than binary trees.
Upvotes: 1