简体   繁体   中英

Binary Search Tree - Memory Leak at insertion

I am trying to create a binary search tree and insert a new node in an iterative way. It is all working well except I am getting a memory leak in this function.

Valgrind says 7 blocks (I am adding 7 nodes) are missing. I couldn't see where my leak is. I would appreciate another look at my code.

void bst_insert_node(bstree* bst, unsigned long phone, char *name) {
    bst_node* current = bst->root;

    bst_node* parent = NULL;

    bst_node* new = (bst_node *)malloc(sizeof(bst_node));
    new->phone  = phone;
    new->left   =   new->right  =   new->parent =   NULL;
    new->name = malloc(sizeof(char) * (strlen(name)+1));
    strncpy(new->name,name,(strlen(name)+1));

    while(current != NULL) {

        parent = current;

        if(phone < current->phone) {
            current = current -> left;
        }
        else if(phone > current->phone) {
            current = current -> right;
        } else {
            free(new);
            printf("Diese Nummer ist schon bekannt \n");
            return;
        }
    }

    new->parent = parent;

    if(parent == NULL) {
        bst->root = new;
    }
    else if(new->phone < parent->phone) {
        parent->left = new;
    }
    else {
        parent->right = new;
    }
}

Free methods:

void bst_free_subtree(bst_node* node) {
if (node == NULL) return;

bst_free_subtree(node->left);
bst_free_subtree(node->right);
printf("\n Deleting node: %lu \t %s", node->phone,node->name);
free(node);}

void bst_free_tree(bstree* bst) {
    if(bst != NULL && bst->root != NULL) {
        bst_free_subtree(bst->root);
        bst->root = NULL;
    }
}

As we all discussed in the comments, your memory leak is that you're not freeing the node->name strings that you have allocated. You need to add two more free s to your code:

  • in bst_insert_node, in the case where you can't insert the node, free(new->name) before you free(new)
  • in bst_free_subtree, free(node->name) before you free(node)

There is also an off-by-one error allocating space for a copied string, as in your answer. It might be simplest to just new->name = strdup(name) instead, which will do both the allocate and the copy in one go.

As an aside, if these are phone numbers then I'd probably store them as strings, not integers (or libphonenumber if you want to go the whole hog, but C++ not C) and if there's a problem inserting one then it might be better to return the error to the calling code (eg return true if inserted, false if not) and let that raise errors rather than printing from this code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM