[英]Segmentation fault on binary tree
I'm working on a program that searches through a program and outputs the number of times it comes across a number greater than or equal to the value specified in the parameter of the function.我正在开发一个程序,该程序搜索程序并输出它遇到大于或等于函数参数中指定的值的数字的次数。 I have attached my code below, I see it traverses two of the values before a segmentation fault occurs.
我在下面附上了我的代码,我看到它在发生分段错误之前遍历了两个值。 The segmentation fault error points to
return count + count_values(value, here) + count_values(value, current);
分段错误错误指向
return count + count_values(value, here) + count_values(value, current);
typedef struct BinaryTree {
int val;
struct BinaryTree *left;
struct BinaryTree *right;
} BinaryTree;
BinaryTree *build_tree(int value, BinaryTree *leftnode, BinaryTree *rightnode) {
BinaryTree *out = calloc(1, sizeof(BinaryTree));
out->val = value;
out->leftnode = leftnode;
out->rightnode = rightnode;
return out;
}
int count_values(int value, BinaryTree *tree) {
BinaryTree *current = tree;
BinaryTree *here = current;
int count = 0;
if (current != NULL) {
printf("Value in tree is not NULL\n");
if (current->val < value) {
printf("%d < %d\n", current->val, value);
printf("Count value: %d\n", count);
here = current->leftnode;
count_values(value, here);
current = current->rightnode;
count_values(value, current);
} else if (current->val == value) {
printf("%d = %d\n", current->val, value);
count++;
printf("Count value: %d\n", count);
here = current->leftnode;
count_values(value, here);
current = current->rightnode;
count_values(value, current);
} else {
printf("%d > %d\n", current->val, value);
count++;
printf("Count value: %d\n", count);
here = current->leftnode;
count_values(value, here);
current = current->rightnode;
count_values(value, current);
}
}
return count + count_values(value, here) + count_values(value, current);
}
int main(void) {
BinaryTree *tree =
build_tree(14, build_tree(3, NULL, NULL),
build_tree(15, NULL, build_tree(42, NULL, NULL)));
//path is 14->15->42
int count = count_values(42, tree);
printf("should have a count of 1, got %d\n", count);
count = count_values(14, tree);
printf("should have a count of 3, got %d\n", count);
return 0;
}
For starters there are typos in the both functions as for example对于初学者来说,这两个功能都有拼写错误,例如
out->leftnode = leftnode;
out->rightnode = rightnode;
and和
here = current->leftnode;
current = current->rightnode;
You have to write你必须写
out->left = leftnode;
out->right = rightnode;
and和
here = current->left;
current = current->right;
Within the function count_values
already this if statement在函数
count_values
已经有这个 if 语句
if (current->val != NULL) {
invokes undefined behavior.调用未定义的行为。
First of all it does not make a sense.首先,它没有任何意义。 And secondly before accessing data members of a node you need to check whether the pointer
current
(more precisely the pointer tree
) is a null pointer or not.其次,在访问节点的数据成员之前,您需要检查指针
current
(更准确地说是指针tree
)是否为空指针。
Pay attention to that such statements like these注意像这样的陈述
count_values(value, here);
count_values(value, current);
in fact have no effect.实际上没有任何效果。
The recursive function could be defined the following way递归函数可以通过以下方式定义
size_t count_values( const BinaryTree *tree, int value )
{
return tree == NULL
? 0
: ( tree->val >= value ) + count_values( tree->left, value ) + count_values( tree->right, value );
}
The pointer to the tree should be the first function parameter and declared with the qualifier const
because the function does not change the tree.指向树的指针应该是第一个函数参数并使用限定符
const
声明,因为该函数不会更改树。 And the function should return an object of an unsigned integer type because the counter can not be a negative value.并且该函数应该返回一个无符号整数类型的对象,因为计数器不能是负值。 Instead of the return type
size_t
you may use for example the type unsigned int
.您可以使用例如
unsigned int
类型而不是返回类型size_t
。
Here is a demonstration program.这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
typedef struct BinaryTree {
int val;
struct BinaryTree *left;
struct BinaryTree *right;
} BinaryTree;
BinaryTree *build_tree(int value, BinaryTree *leftnode, BinaryTree *rightnode) {
BinaryTree *out = calloc(1, sizeof(BinaryTree));
out->val = value;
out->left = leftnode;
out->right = rightnode;
return out;
}
size_t count_values( const BinaryTree *tree, int value )
{
return tree == NULL
? 0
: ( tree->val >= value ) + count_values( tree->left, value ) + count_values( tree->right, value );
}
int main(void) {
BinaryTree *tree =
build_tree(14, build_tree(3, NULL, NULL),
build_tree(15, NULL, build_tree(42, NULL, NULL)));
//path is 14->15->42
size_t count = count_values( tree, 42);
printf("should have a count of 1, got %zu\n", count);
count = count_values(tree, 14 );
printf("should have a count of 3, got %zu\n", count);
return 0;
}
Its output is它的输出是
should have a count of 1, got 1
should have a count of 3, got 3
You're making this way harder than it needs to be.你让这种方式变得比它需要的更难。
First test for the base case by testing whether tree
is NULL
.首先通过测试
tree
是否为NULL
来测试基本情况。
If not, recurse on the left and right nodes, and add these counts to the count for the current node.如果不是,则在左右节点上递归,并将这些计数添加到当前节点的计数中。
int count_values(int value, BinaryTree *tree) {
if (tree == NULL) {
return 0;
}
int count = tree->val >= value;
count += count_values(value, tree->left);
count += count_values(value, tree->right);
return count;
}
if (current->val != NULL) {
current->value can never be NULL pointer as value isn't pointer.if (current->val != NULL) {
current->value 永远不能是 NULL 指针,因为值不是指针。 It is just int.current
instead of current->val
current
而不是current->val
return count + count_values(value, here) + count_values(value, current);
return count + count_values(value, here) + count_values(value, current);
linePS the code you posted needed some adjustments to build. PS您发布的代码需要一些调整才能构建。 Fix it if you can
可以的话修一下
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.