Reputation: 6034
I have a C
program that implements trees. my cleanup function looks like this:
void cleanup_tree( TreeNode* root ){
printf("Called\n");
if(root->left!=NULL){
cleanup_tree(root->left);
}
if(root->right!= NULL){
cleanup_tree(root->right);
}
if(root->right==NULL &&root->left==NULL) {
/*free(root);*/
free(root->word);
free(root);
root = NULL;
}
}
My Tree struct has
typedef struct TreeNode_st {
char *word; // the word held in this node
unsigned int frequency; // how many times it has been seen
struct TreeNode_st *left; // node's left child
struct TreeNode_st *right; // node's right child
} TreeNode;
I am initialising a tree like this :
TreeNode* initTreeNode(){
TreeNode *mainNode= (TreeNode*)malloc(sizeof(TreeNode));
mainNode->frequency = 0 ;
mainNode->word = NULL;
mainNode->left = NULL;
mainNode->right = NULL;
return mainNode;
}
in my main
, I have called
TreeNode *mainNode =initTreeNode();
and I'm doing operations on it , and just before program exit, i called
cleanup_tree(mainNode);
Valgrind reported memory leaks, so just to test , i did
I put
printf("~~~FINAL NULL TEST %s",mainNode->left->right->word);
below my cleanup_tree line,
And i'm able to see the word even now.
What am I doing wrong ?
Upvotes: 0
Views: 63
Reputation: 225517
You seem to be under the impression that setting root = NULL
at the end of this function will be visible in the calling function so that the third if
block gets called. That's not the case.
You want to always free()
the word
as well as the node itself.
void cleanup_tree( TreeNode* root ){
printf("Called\n");
if(root->left!=NULL){
cleanup_tree(root->left);
}
if(root->right!= NULL){
cleanup_tree(root->right);
}
free(root->word);
free(root);
}
Upvotes: 0
Reputation: 25286
There are two ways:
void cleanup_tree( TreeNode **root)
Currently, the changes made by the function are not reflected in the node parameter you passed.
Ad 2:
cleanup_tree(root->right);
root->right= NULL;
Upvotes: 1