0

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 ?

5
  • Looks like if(root->right==NULL &&root->left==NULL) { only frees nodes with no children? Commented Oct 13, 2016 at 16:41
  • i am calling that function recursively, so It should to go the edges, set them free, so the parent will now be a node that has no children, and it will go up to the root Commented Oct 13, 2016 at 16:42
  • The variables don't set themselfs magically to NULL though. Commented Oct 13, 2016 at 16:43
  • but i am setting a non null ROOT to NULL after freeing it. Commented Oct 13, 2016 at 16:44
  • 1
    That's a local variable, so not visible outside of your function. Commented Oct 13, 2016 at 16:45

2 Answers 2

1

There are two ways:

  1. You pass it a pointer-to-a-pointer: void cleanup_tree( TreeNode **root)
  2. You set the fields to NULL after the cleanup returns:

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; 
Sign up to request clarification or add additional context in comments.

Comments

0

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); } 

3 Comments

when I removed my if (left node and right node are both null) condition , i get segmentation fault
@harvey_slash There must be some other issue, then. What does valgrind say?
@Paul Ogilvie's answer worked, if im setting left and right to NULL, valgrind is happy

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.