[英]Valgrind errors due to freed memory?
I am getting these Valgrind errors but really don't know what I did wrong.我收到了这些 Valgrind 错误,但真的不知道我做错了什么。 I'm assuming I am using pointers that point at a free memory location.
我假设我正在使用指向空闲 memory 位置的指针。 Any help?
有什么帮助吗?
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);
}
One way to catch some of these things on your own is to make it a point to always null out any pointer you have freed so it won't ever have a lingering reference.自己捕获其中一些内容的一种方法是,始终将 null 指向您已释放的任何指针,这样它就不会有挥之不去的引用。
Node* freeSubtree(Node *N) { if(!N) return;
freeSubtree(N->left);
free(N); N = NULL; // NULL out the pointer!
freeSubtree(N->right);
}
and of course @Johnny Mopp has pointed out the actual bug that requires you to move the free()
to the end.当然,@Johnny Mopp 已经指出了需要您将
free()
移到最后的实际错误。
In practice for code like this, I get even more aggressive in C with any function that might free memory by passing the address of the pointer so the address itself can be nulled out in the caller .在这样的代码的实践中,我在 C 中变得更加激进,任何 function 可能会通过传递指针的地址来释放 memory,因此地址本身可以被传入调用者。
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
}
If you want to use this technique, you really have to go all-in because the address-of-pointer parameter typically gets pretty widespread, but it's a godsend to never ever have use-after-free bugs.如果你想使用这种技术,你真的必须全押 go 因为指针地址参数通常非常普遍,但永远不会有释放后使用错误是天赐之物。
Edit: use-after-free bugs are not always just bugs, sometimes they are security bugs.编辑:释放后使用错误并不总是错误,有时它们是安全错误。
Note: in C++ you can use ref parameters to do this far more readably.注意:在 C++ 中,您可以使用 ref 参数来提高可读性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.