我无法正确释放二叉树,我该如何调试它?
i can't free binary tree correctly, how could i debug it?
我弄了个二叉树玩猜用户猜的游戏。
在我尝试释放二叉树之前,一切都很好。
我用 valgrind 检查,他们给了我这些:
==8205== Invalid read of size 8
==8205== at 0x400F0A: treePrint (in /home/mbax4nc2/COMP26120/ex6/pangolin)
==8205== by 0x400A14: main (in /home/mbax4nc2/COMP26120/ex6/pangolin)
==8205== Address 0x4c334a8 is 200 bytes inside a block of size 216 free'd
==8205== at 0x4A06430: free (vg_replace_malloc.c:446)
==8205== by 0x400DEE: freeTree (in /home/mbax4nc2/COMP26120/ex6/pangolin)
==8205== by 0x400A08: main (in /home/mbax4nc2/COMP26120/ex6/pangolin)
typedef struct node{
char name[100];
char question[100];
struct node *yes;
struct node *no;
}node;
void freeTree(node *root)
{ //Tree's root note is passed as argument
if (root == NULL)
{
return;
}
if (root->no != NULL)
{
freeTree(root->no);
root->no = NULL;
}
if (root->yes != NULL)
{
freeTree(root->yes);
root->yes = NULL;
}
free(root);
return;
}
我没有把我所有的程序都贴在这里,因为它真的是一个很长的版本。我的 free() 函数有什么问题?我该如何调试它?我不知道如何使用 valgrind 记录来修复我的程序。
就这么简单:
void freeTree(node *root)
{
if (!root )
return;
freeTree(root->no);
freeTree(root->yes);
free(root);
return;
}
在我看来,错误可能不是由自由函数引起的,而是代码中的其他地方引起的。你的免费功能对我来说看起来还不错,尽管它可能像 milevyo 的回答那样更简单。如果我不得不猜测,我会说你没有正确初始化 yes 和 no 指向 null 的指针。默认情况下,它们将指向一些无效的内存。每次添加新节点时都需要将它们设置为 null。如果您发布其余代码,将会有所帮助。
其实我刚看评论,你说你打free后打print。只要您在调用 freeTree 后将根节点设置为 null(假设您的 print 函数正确处理空的 null 树),这应该就可以工作。我注意到这个函数不会改变根节点,即使它释放了它。 free 函数不会更改指针的值,并且该指针仍将指向相同的位置。为了安全起见,我总是在释放它们后将指针设置为 null。
调试动态内存管理:计算对 malloc()
、calloc()
、realloc(NULL, ...)
和 strdup()
的所有调用,将它们相加,然后计算对 [= 的所有调用14=],不包括对 free(NULL)
的调用。如果你没有发现错误,前者和后者的计数应该匹配。
请注意:如果上述两个计数匹配,这不意味着内存管理正确。
我弄了个二叉树玩猜用户猜的游戏。 在我尝试释放二叉树之前,一切都很好。 我用 valgrind 检查,他们给了我这些:
==8205== Invalid read of size 8
==8205== at 0x400F0A: treePrint (in /home/mbax4nc2/COMP26120/ex6/pangolin)
==8205== by 0x400A14: main (in /home/mbax4nc2/COMP26120/ex6/pangolin)
==8205== Address 0x4c334a8 is 200 bytes inside a block of size 216 free'd
==8205== at 0x4A06430: free (vg_replace_malloc.c:446)
==8205== by 0x400DEE: freeTree (in /home/mbax4nc2/COMP26120/ex6/pangolin)
==8205== by 0x400A08: main (in /home/mbax4nc2/COMP26120/ex6/pangolin)
typedef struct node{
char name[100];
char question[100];
struct node *yes;
struct node *no;
}node;
void freeTree(node *root)
{ //Tree's root note is passed as argument
if (root == NULL)
{
return;
}
if (root->no != NULL)
{
freeTree(root->no);
root->no = NULL;
}
if (root->yes != NULL)
{
freeTree(root->yes);
root->yes = NULL;
}
free(root);
return;
}
我没有把我所有的程序都贴在这里,因为它真的是一个很长的版本。我的 free() 函数有什么问题?我该如何调试它?我不知道如何使用 valgrind 记录来修复我的程序。
就这么简单:
void freeTree(node *root)
{
if (!root )
return;
freeTree(root->no);
freeTree(root->yes);
free(root);
return;
}
在我看来,错误可能不是由自由函数引起的,而是代码中的其他地方引起的。你的免费功能对我来说看起来还不错,尽管它可能像 milevyo 的回答那样更简单。如果我不得不猜测,我会说你没有正确初始化 yes 和 no 指向 null 的指针。默认情况下,它们将指向一些无效的内存。每次添加新节点时都需要将它们设置为 null。如果您发布其余代码,将会有所帮助。
其实我刚看评论,你说你打free后打print。只要您在调用 freeTree 后将根节点设置为 null(假设您的 print 函数正确处理空的 null 树),这应该就可以工作。我注意到这个函数不会改变根节点,即使它释放了它。 free 函数不会更改指针的值,并且该指针仍将指向相同的位置。为了安全起见,我总是在释放它们后将指针设置为 null。
调试动态内存管理:计算对 malloc()
、calloc()
、realloc(NULL, ...)
和 strdup()
的所有调用,将它们相加,然后计算对 [= 的所有调用14=],不包括对 free(NULL)
的调用。如果你没有发现错误,前者和后者的计数应该匹配。
请注意:如果上述两个计数匹配,这不意味着内存管理正确。