Search code examples
cposix

How can you clean an entire POSIX tree with only POSIX functions?


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?


Solution

  • 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().