我得到这些瓦尔格林的错误,但真的不知道我做错了什么。我假设我正在使用指向空闲内存位置的指针。有什么帮助吗?
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/