But, again, it would be nice to rewrite this iteratively, both because
the iterative version is likely to be faster and for the sheer mental
exercise of it. Recall, from our earlier discussion of inorder
traversal, that tail recursion (recursion where a function calls itself
as its last action) is easier to convert to iteration than other types.
Unfortunately, neither of the recursive calls above are tail-recursive.

Fortunately, we can rewrite it so that it is, if we change the way we
allocate data:

1. When malloc() returns a null pointer, bst_copy_recursive_1() fails
“silently”, that is, without notifying its caller about the error, and
the output is a partial copy of the original tree. Without removing the
recursion, implement two different ways to propagate such errors upward
to the function's caller:

Without changing the function's prototype. (Hint: use a statically
declared structbst_node).

In each case make sure that any allocated memory is safely freed if an
allocation error occurs.
[answer]

2.bst_copy_recursive_2() is even worse than bst_copy_recursive_1()
at handling allocation failure. It actually invokes undefined
behavior when an allocation fails. Fix this, changing it to return an
int, with nonzero return values indicating success. Be careful not
to leak memory.
[answer]