harveyslash
harveyslash

Reputation: 6034

Not able to free memory from function

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

Answers (2)

dbush
dbush

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

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

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;

Upvotes: 1

Related Questions