给定:deleteTree()函数删除树,但不会将root更改为NULL,如果deleteTree()的用户没有将root更改为NULL并尝试使用root指针访问值,则可能会导致问题。我们可以修改deleteTree()函数来引用根节点,这样就不会发生这个问题。
[链接] http://www.geeksforgeeks.org/write-a-c-program-to-delete-a-tree/
怀疑:在deleteTree函数中,传递了main节点的副本,然后如何在deleteTree()中释放所有这些节点的实际内存。据说树被删除但是要删除的树不应该传递地址。此外,如果我们认为树实际上已被删除,那么根节点也会被删除,那么为什么它不会在主节点中变为NULL?
void deleteTree(struct node* node)
{
if (node == NULL) return;
deleteTree(node->left);
deleteTree(node->right);
printf("\n Deleting node: %d", node->data);
free(node);
}
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
deleteTree(root);
root = NULL;
printf("\n Tree deleted ");
getchar();
return 0;
}
修改后的代码:
void _deleteTree(struct node* node)
{
if (node == NULL) return;
_deleteTree(node->left);
_deleteTree(node->right);
printf("\n Deleting node: %d", node->data);
free(node);
}
void deleteTree(struct node** node_ref)
{
_deleteTree(*node_ref);
*node_ref = NULL;
}
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
deleteTree(&root);
printf("\n Tree deleted ");
getchar();
return 0;
}
如果我们在main中而不是在deleteTree函数中设置root = NULL,那么在这种情况下如何释放呢?
答案 0 :(得分:0)
你混淆了两个概念 - 内存释放,并将指针设置为NULL
。通过使用free
释放内存,指针现在指向未分配的内存。通过将节点*设置为NULL,您指示指针无效 - 您可以看到代码检查了该指针 - if (node ==
NULL ) return;
。如果只是将root设置为NULL,则会产生内存泄漏,因为指向的内存仍然是已分配的。
此外 - It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address
- 您正在传递地址 - deleteTree(&root);
- root是包含根节点地址的节点*。
希望这有帮助。
答案 1 :(得分:0)
在第一个代码中,函数void deleteTree(struct node* node)
调用自身(递归)来释放每个节点的内存。It is said the tree is deleted but for the tree to be deleted shouldn't we pass the address
,实际上para node
是一个节点的地址,它是一个指针(struct node *
)。当你拨打free(node)
时,释放node
指向的内存,而不是节点本身。
至于将root设置为NULL
,第二个代码与逻辑上的第一个代码相同。如果函数void deleteTree(struct node** node_ref)
是内联的,那么在编译之后,它将与您的第一个代码相同。