我得到这些瓦尔格林的错误,但真的不知道我做错了什么。我假设我正在使用指向空闲内存位置的指针。有什么帮助吗?
c - Valgrind因释放内存而出错?-LMLPHP

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

}

最佳答案

一种可以自己捕捉这些内容的方法是,让它成为一个点,总是空掉您释放的任何指针,这样它就永远不会有一个挥之不去的引用。

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

  freeSubtree(N->left);

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

  freeSubtree(N->right);
}

当然,@Johnny Mopp指出了实际的bug,它要求您将free()移到末尾。
在类似这样的代码的实践中,我在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
}

如果你想使用这种技术,你真的必须全力以赴,因为指针参数的地址通常会变得非常广泛,但这是一个天赐良机,从来没有使用后,免费的错误。
编辑:免费后使用的bug并不总是bug,有时它们是安全bug。
注意:在C++中,您可以使用REF参数来进行更为可读的操作。

关于c - Valgrind因释放内存而出错?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58598072/

10-10 12:30