我正在尝试使用treePrint函数来打印树,但是在打印硬编码树时遇到问题。 当递归调用它时,它给了我一个分段错误,我不确定如何解决它。 我认为问题在于我使用指针的方式,但我无法弄清楚如何解决它。
有人可以解释我做错了什么吗?
谢谢
#include<stdlib.h>
#include<stdio.h>
struct node
{
char* objectName;
char* question;
struct node *yes_ptr;
struct node *no_ptr;
};
void nodePrint(struct node *ptr)
{
printf("objectName: %sn", ptr->objectName );
printf("question: %sn", ptr->question );
}
void treePrint(struct node *ptr)
{
printf("yes pointern" );
if (ptr == NULL)
{
//do nothing
}
else
{
if (strcmp( ptr->objectName, "Q") == 0)
{
printf("question: %sn", ptr->question );
//now print the yes and no subtrees:
treePrint((ptr->yes_ptr));
treePrint(ptr->no_ptr);
}
else
{ // ptr is an object
printf("objectName: %sn", ptr->objectName );
}
}
}
int main(int argc, char **argv)
{
struct node *nodes[20];
struct node *node1 = malloc(sizeof(nodes));
node1->objectName = "Q";
node1->question = "Does it have a tail?";
node1->yes_ptr = nodes[0]+1;
node1->no_ptr = nodes[0]+2;
nodes[0] = node1;
struct node *node2 = malloc(sizeof(nodes));
node2->objectName = "Q";
node2->question = "Does it like to chase mice?";
node2->yes_ptr = nodes[0]+2;
node2->no_ptr = nodes[0]+4;
nodes[1] = node2;
treePrint(nodes[0]);
}
您的指针算法不正确。这里:
nodes[0] + 1;
您在node[0]
之后立即引用节点。这只有在节点是连续数组的一部分时才有效,但事实并非如此:它是堆上的单个节点。
您可以通过仅引用nodes[1]
来解决此问题。您应该首先将所有节点初始化为NULL
:
struct node *nodes[20] = {NULL};
为了捕捉悬空的节点。例如,您在代码中引用节点 4,但尚未定义该节点。
如果要使用此方法,则必须向后定义节点,即必须在父节点之前定义子节点,以便父节点可以引用实际节点。此方法还要求您在程序结束时释放所有节点。
这可能不是你想要的。相反,使数组成为节点数组,而不是指向节点的指针数组:
struct node node[20];
然后,您可以使用指针算法创建指向此数组中节点的指针。确保在没有链接的地方显式使用NULL
:
node[0].objectName = "Q";
node[0].question = "Does it have a tail?";
node[0].yes_ptr = node + 1;
node[0].no_ptr = NULL;
请注意,您没有显式分配任何内容,因此无需担心释放内存。这就是对树进行硬编码的意义所在。
您甚至可以通过直接初始化树来做得更好,而无需手动显式填写所有值:
struct node node[] = {
{"Q", "Does it have a tail?", node + 1, node + 2},
{"Q", "Does it like to chase mice?", node + 4, node + 3},
{"A", "It's a Manx cat!", NULL, NULL},
{"A", "It's a musophobic cat!", NULL, NULL},
{"A", "It's just a normal cat!", NULL, NULL}
};