@cooper1200,
You've just repeated the same lesson we've gone through on the manipulation of Bin_Tree's root inside your AVL code.
I think you have developed a belief that somehow a variable and the memory location returned by malloc are married into a kind of unified concept, but they're not.
To demonstrate:
Code:
Bin_Tree *t1 = malloc( sizeof( Bin_Tree ) );
Bin_Tree *t2 = t1;
Bin_Tree *t3 = t2;
All three, t1, t2, and t3 point to the same address given by malloc
Now
Code:
free( t3 );
t3 = null;
At this point, t3 is null and the memory is freed.
However, t1 and t2 still hold their pointer to that memory, even though the memory is freed, and if t1 and t2 use that pointer to see inside Bin_Tree, it will crash.
Another to drive this home....
Code:
Bin_Tree *t1 = malloc( sizeof( Bin_Tree ) );
destroy( t1 );
void destroy( Bin_Tree * t1 )
{
free( t1 );
t1 = NULL;
}
No matter what the name of the parameter in destroy, the memory is freed (as in the first example), but t1 is only set to NULL in the function. It is a copy of the pointer, so the caller of destroy still has a pointer to what malloc returned, but it still has been freed in destroy.
The only way a function can modify the parameter passed to it is with the idiom you've used for AVL tree insertion, like
Code:
Bin_Tree *t1 = malloc(.....);
destroy( &t1 ); /// the address of t1 is a pointer to a pointer of Bin_Tree
void destroy( Bin_Tree ** t1 )
{
free( t1 );
t1 = NULL;
}