【发布时间】:2015-02-24 19:59:14
【问题描述】:
我的 C 程序中的某个函数出现问题。该计划的目的是:
- 将二进制文件中的整数读取到数组中
- 使用二叉树对这些数字进行排序
- 做一些其他的事情
- 释放您使用 malloc() 分配的所有内存;
除了能够释放我的二叉树之外,我一切正常。这是我的树和节点(又名叶子)的结构。
typedef struct Node *NodeP;
typedef struct Tree *TreeP;
// Definition of a tree
struct Tree
{
NodeP root;
}Tree;
// Definition of a node
struct Node
{
int data;
NodeP L, R;
}Node;
在我的程序中,我使用 malloc 为我的树和每个单独的节点分配内存。所以我调用了一个函数来释放树及其所有节点。
/*
* Frees the memory allocated for
* each node
*/
void freeNode(NodeP p)
{
if(p == NULL) return;
freeNode(p->L);
freeNode(p->R);
free(p);
}
/*
* Frees the memory allocated
* for the tree
*/
TreeP freeTree(TreeP tree)
{
if(tree->root == NULL)
free(tree);
else
{
freeNode(tree->root);
free(tree);
}
return NULL;
}
当我运行这个程序时,我的调试器给了我这个错误。
EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
我已经尝试过每次递归迭代,但我找不到它为什么给我一个错误。我在想它是在边缘情况下从树的边缘掉下来的?我不知道。非常感谢任何帮助!
编辑:
这里是下载完整程序的链接。我包含了一个自述文件和我正在使用的二进制文件。一个只有 10 个整数长度,另一个是 20000 长度。感谢您迄今为止的帮助!
【问题讨论】:
-
为什么不看一下调用栈来实现,问题出在哪里? (至少,在什么级别)
-
我可以看到两个不寻常的构造(
freeNode中的p = NULL和从freeTree返回的NULL),但这些都不应该是你问题的根源(但我会无论如何都要摆脱它们)。我怀疑您已经在其他地方浪费了您的堆,并且问题仅在您遍历树以释放节点时才显现出来。看看别处。 -
我认为实现没有明显错误,因此您必须使用带有小树的调试器来查找问题。树可能格式不正确,例如多个父母指向同一个孩子,或者某些指针未正确初始化,但这些类型的问题不在您共享的代码中。旁注:
freeNode末尾的行p = NULL;什么都不做,应该删除。 -
您是否真的为包含单个指针的根结构分配了内存,您
free()?这是一种奇怪的做法:树根通常是指向第一个节点的指针。 -
$64:当您构建该树时,您是否确保所有叶节点的左右子树指针都为 NULL?
freeTree函数应该只需要if (tree) { freeNode(tree->root); free(tree); }顺便说一句。在您的链接代码中,malloc(sizeof(TreeP));不是您想要的。这正好为指针的大小分配内存,而不是Tree节点的大小,如果您没有不明智地将指针类型隐藏在 typedef 中,您可能不会犯这个错误。
标签: c tree malloc binary-tree free