Valgrind错误是由于释放了内存?

问题描述 投票:0回答:1

我收到这些Valgrind错误,但实际上不知道我做错了什么。我假设我使用的指针指向空闲内存位置。有帮助吗?

enter image description here

Node* insertNode(Node *root, int value){

    if(!root) {
        root = malloc(sizeof(struct Node));
        root->data = value;
        root->left = root->right = NULL;
    }
    else if(value > root->data && root->right) {
        insertNode(root->right, value);
    }
    else if(value > root->data && !root->right) {
        root->right = insertNode(root->right, value);
    }
    else if(root->left) {
        insertNode(root->left, value);
    }
    else {
        root->left = insertNode(root->left, value);
    }

    return root;

}

Node* deleteNode(Node *root, int value) {

    if (root == NULL) 
        return root; 

    else if (value < root->data) {
        root->left = deleteNode(root->left, value); 
    }

    else if (value > root->data) {
        root->right = deleteNode(root->right, value); 
    }

    else if (root->left == NULL) { 
        Node *temp;
        temp = root->right; 
        free(root); 
        return temp; 
    } 

    else if (root->right == NULL) { 
        Node *temp;
        temp = root->left; 
        free(root); 
        return temp; 
        }  

    else {
        Node *temp;
        temp = smallestNode(root->right); 
        root->data = temp->data; 
        root->right = deleteNode(root->right, temp->data); 
    } 

    return root; 

}

Node* freeSubtree(Node *N) { if(!N) return;

    freeSubtree(N->left);
    free(N);
    freeSubtree(N->right);

}
c valgrind
1个回答
0
投票

一种自行捕获其中某些内容的方法是,使所有已释放的指针始终为空,这样它就永远不会留下持久的引用。

Node* freeSubtree(Node *N) { if(!N) return;

  freeSubtree(N->left);

  free(N); N = NULL;          // NULL out the pointer!

  freeSubtree(N->right);
}

当然,@ Johnny Mopp指出了需要您将free()移至末尾的实际错误。

对于这样的代码,在实践中,我使用任何可能通过传递指针的[[address释放内存,以便地址本身可以在[[在调用程序中]清空]的函数,在C语言中变得更加积极。 Node *freeSubtree(Node **PN) { if (!PN || !*PN) return; freeSubtree( &( (*PN)->left) ); // frees and NULLs the ->left pointer freeSubtree( &( (*PN)->right) ); // frees and NULLs the ->right pointer free(*PN); *PN = NULL; // NULL the *caller's* handle on the pointer }

如果您想使用此技术,那么您真的必须全力以赴,因为指针地址参数通常会变得相当普遍,但这是从来没有使用过售后漏洞的天赐之赐。
注意:在C ++中,您可以使用ref参数使此操作更加可读。
© www.soinside.com 2019 - 2024. All rights reserved.