[英]Binary tree in C - Segmentation fault
#include <stdio.h>
#include <stdlib.h>
typedef struct nod{
int data;
struct nod *left,*right;
}NOD;
NOD * generate(NOD * root)
{
NOD *r,*p;
int d=-1,value,line,position,i,f,v;
if(root==NULL)
{
do{
printf("Would you like to create the root node?\n\n1 - yes\n0 - no\n");
scanf("%d",&d);
switch(d)
{
case 1:
printf("Value=");
scanf("%d",&value);
root=add_root(value);
break;
case 0:
return NULL;
break;
default:
printf("Command unrecognized!\n");
break;
}
} while(d==-1);
if(root!=NULL)
printf("Root node successfully created!\n");
else
printf("Error: could not create root node!\n");
d=-1;
do{
printf("Continue adding nodes?\n\n1 - yes\n0 - no\n");
scanf("%d",&d);
switch(d)
{
case 1:
printf("Insert the line and the position of the node you wish to add (root node has line=0, position=0)\nLine=");
scanf("%d",&line);
printf("Position ( less or equal with 2^$line-1 )=");
scanf("%d",&position);
printf("Value=");
scanf("%d",&value);
r=p=root;
for(i=line-1;i=0;i--)
{
f=power(2,i);
if(position & f == f) // if the i-(st,nd,rd,th) bit of "position" is 1, then (position & f == f) is true and *r will go right
{
p=r;
r=r->right;
v=1;
}
else
{
p=r;
r=r->left;
v=0;
}
}
if(v==0)
p=add_left(&r,value);
if(v==1)
p=add_right(&r,value);
break;
case 0:
return root;
break;
default:
printf("Command unrecognized!\n");
break;
}
} while(d==-1);
}
else
{
...
}
NOD * add_left(NOD **p,int value)
{
NOD * r;
r=malloc(sizeof(NOD));
r->data=value;
r->left=NULL;
r->right=NULL;
(*p)->left=r;
return r;
}
NOD * add_right(NOD **p,int value)
{
NOD * r;
r=malloc(sizeof(NOD));
r->data=value;
r->left=NULL;
r->right=NULL;
(*p)->right=r;
return r;
}
NOD * add_root(int value)
{
NOD * x;
x=malloc(sizeof(NOD));
x->data=value;
x->left=NULL;
x->right=NULL;
return x;
}
}
int main() {
NOD *root=NULL;
root=generate(root);
return 0;
}
I tried make a program that creates a binary tree but I keep getting SIGSEGV Segmentation fault and I don't understand why. 我尝试过创建一个创建二叉树的程序,但是我不断收到SIGSEGV Segmentation错误,但我不明白为什么。 Can you please tell me what I did wrong?
你能告诉我我做错了什么吗?
if(position & f == f) // if the i-(st,nd,rd,th) bit of "*position*" is 1,
// then (position & f == f) is true and *r will go right
What do you think about this part? 您如何看待这部分?
line is the level of the tree (root has line=0) line是树的级别(根有line = 0)
position is the position of node from left to right (root has position=0) position是节点从左到右的位置(根的位置为= 0)
You already have bolded a problematic part: 您已经加粗了一个有问题的部分:
if(position & f == f)
==
has higher precedence than &
, so that is parsed as ==
优先级比&
优先级高,因此被解析为
if(position & (f == f))
and is the same as if (position & 1)
, not what you want. 并且与
if (position & 1)
,而不是您想要的。
Further, you have the wrong loop condition 此外,您有错误的循环条件
for(i=line-1;i=0;i--)
the test should probably be i >= 0
, otherwise the loop is never executed ( i = 0
is an assignment that evaluates to 0). 测试可能应该是
i >= 0
,否则循环永远不会执行( i = 0
是赋值为0的赋值)。
If these are fixed and the loop is executed, after the first iteration r
is a nullpointer, then the next loop iteration causes the crash in r = r->right;
如果这些是固定的,并且执行了循环,则在第一个迭代
r
为空指针之后,则下一个循环迭代将导致崩溃,原因是r = r->right;
, or, if the loop iterates only once, add_left(&r,value);
,或者,如果循环仅迭代一次,则
add_left(&r,value);
(or add_right
) dereferences a nullpointer on the penultimate line trying to access its left
(resp. right
) pointer: (或
add_right
)在倒数第二行上取消引用空指针,以尝试访问其left
指针(分别为right
):
NOD * add_left(NOD **p,int value)
{
NOD * r;
r=malloc(sizeof(NOD));
r->data=value;
r->left=NULL;
r->right=NULL;
(*p)->left=r; // *p == NULL here
return r;
}
In this line 在这条线
for(i=line-1;i=0;i--)
I think you meant 我想你是说
for(i=line-1;i!=0;i--)
Otherwise the loop will not execute ( i=0
evaluates to false
). 否则,循环将不会执行(
i=0
为false
)。 which causes v
to have undefined value (as it is never initialized). 这导致
v
具有未定义的值(因为它从未被初始化)。 While this most likely will not result in segfault, it will cause memory leak as you overide the left/right subtree of the root. 尽管这很可能不会导致段错误,但是当您覆盖根的左/右子树时,它将导致内存泄漏。
Also, the default switch
branch does not change the scanned value of d
, which means you proceed with a NULL
root (the error branch that checks for root != NULL
) does not exit the function) 另外,默认的
switch
分支不会更改d
的扫描值,这意味着您将继续使用NULL
根(检查root != NULL
的错误分支root != NULL
不会退出该函数)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.