[英]Segmentation Fault error - binary search tree in C
I'm trying to build a binary search tree.我正在尝试构建二叉搜索树。 Inserting an integer using insert function (only using 1 to 100 for testing) and appending the result to a file using inorder traversal.
使用插入 function 插入 integer(仅使用 1 到 100 进行测试)并使用中序遍历将结果附加到文件中。 However, i'm getting a segmentation fault error.
但是,我遇到了分段错误错误。 Using Visual Studio code on Macbook Pro 2020. Also tested on Codeblocks on Windows - filename.exe stops working and crashes.
在 Macbook Pro 2020 上使用 Visual Studio 代码。还在 Windows 上的代码块上进行了测试 - filename.exe 停止工作并崩溃。
#include <stdio.h>
#include <stdlib.h>
typedef struct node *BST;
struct node {
int data;
BST left;
BST right;
};
BST insert(BST root, int number) {
BST temp = NULL;
if (root == NULL) {
temp = *(BST *)malloc(sizeof(BST));
temp->left = NULL;
temp->right = NULL;
temp->data = number;
root = temp;
}
else if (root->data > number) {
insert(root->left, number);
}
else {
insert(root->right, number);
}
return root;
}
//returning null if number not found and pointer to root if found
BST find(BST root, int number) {
if (root == NULL) {
return NULL;
}
if (root->data > number) {
find(root->left, number);
}
else if (root->data < number) {
find(root->right, number);
}
else (root->data = number);
return root;
}
//printing number to file
void inOrder (BST root, FILE *fp) {
if (root == NULL) return;
inOrder(root->left, fp);
fprintf(fp, "%d", root->data);
inOrder(root->right, fp);
}
int main() {
BST root = NULL;
int n = 100;
int treeArray[n];
for (int r = 0; r < n; r++) {
treeArray[r] = r;
}
root = insert(root, treeArray[0]);
for (int x = 1; x < n; x++) {
insert(root, treeArray[x]);
}
FILE *treefile = fopen("print_tree.txt", "w");
inOrder(root, treefile);
fclose(treefile);
return 0;
}
Error: /bin/sh: line 1: 44278 Segmentation fault: 11 *file path redacted*
What am I doing wrong here?我在这里做错了什么? :(
:(
You declare BST
as:您将
BST
声明为:
typedef struct node *BST;
So, it is a pointer to a struct node
and your problem is probably here:所以,它是一个指向
struct node
的指针,你的问题可能在这里:
temp = *(BST *)malloc(sizeof(BST));
You are allocating memory but the byte size you specified is that of BST
, that is pointer to struct node
, while you want to allocate a struct node
.您正在分配 memory 但您指定的字节大小是
BST
的字节大小,即指向struct node
的指针,而您要分配一个struct node
。
You cast the returned value of malloc
to a pointer to a BST
, that is, a pointer to a pointer to a struct node
.您将
malloc
的返回值转换为指向BST
的指针,即指向struct node
的指针的指针。 And then you de-reference it to assign the result to temp
.然后您取消引用它以将结果分配给
temp
。 So, what you assign to temp
is a pointer to a struct node
(correct) but the pointed object has the wrong size.因此,您分配给
temp
的是指向struct node
的指针(正确),但指向的 object 的大小错误。 Anyway, you should not cast the value returned by malloc
( void *
) .无论如何, 您不应该
malloc
( void *
) 返回的值。
Things are much simpler than you apparently think: if you want to allocate a struct node
(or anything else) pass its size to malloc
.事情比你想象的要简单得多:如果你想分配一个
struct node
(或其他任何东西),请将其大小传递给malloc
。 malloc
returns a void *
pointer to the allocated struct node
that you can assign to any pointer variable without casting. malloc
返回一个指向已分配struct node
的void *
指针,您可以将其分配给任何指针变量而无需强制转换。
Note: you should check the returned value because if malloc
fails it returns NULL
and you should not use that.注意:您应该检查返回的值,因为如果
malloc
失败,它会返回NULL
并且您不应该使用它。
Try this, instead:试试这个,而不是:
temp = malloc(sizeof (struct node));
if(temp == NULL) {
fprintf(stderr, "%s:%d allocation failed\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
I assumed that an allocation error, in your case, is unrecoverable, adapt if it is.我假设在您的情况下分配错误是不可恢复的,如果是,请调整。
Note: you could also, as suggested in comments, use:注意:您也可以按照评论中的建议使用:
temp = malloc(sizeof *temp);
which will always work, by construction.通过施工,这将始终有效。 But as long as you are not completely comfortable with pointers and memory allocation I suggest that you use explicit types with
malloc
.但只要您对指针和 memory 分配不完全满意,我建议您使用带有
malloc
的显式类型。 It is a bit easier to read and understand, even if it is a bit less easy to maintain (if you change the type of temp
).它更容易阅读和理解,即使它不太容易维护(如果你更改
temp
的类型)。
But there are other problems with your code.但是您的代码还有其他问题。 Your
insert
and find
functions are bogus.您的
insert
和find
功能是伪造的。 Understanding why is left as a debugging exercise.理解为什么留作调试练习。
Main problem is with this statement:主要问题在于此声明:
temp = *(BST *)malloc(sizeof(BST));
As it was already explained in the other answer clearly, I am going to skip that.正如其他答案中已经清楚解释的那样,我将跳过它。
So you can do:所以你可以这样做:
temp = malloc(sizeof (struct node));
OR或者
// to add : this helps in case the type of temp ever changes,
temp = malloc(sizeof(*temp));
Other minor logical changes:其他小的逻辑变化:
find
function, there is no need of this else if
statementfind
function中,不需要这个else if
语句 // = or == doesn't matter now
else (root->data = number);
insert
function, you forgot to link the nodes which you insert after your root node.insert
function 中,您忘记链接在根节点之后插入的节点。 So whenever you perform the inorder traversal
, you only get the root node ie 0
in your case.inorder traversal
时,您只会得到根节点,即0
在您的情况下。 Note:笔记:
typedef
is used to make code more readable, but hiding the pointer using typedef creates confusion. typedef
用于使代码更具可读性,但使用 typedef 隐藏指针会造成混乱。 So I would suggest not to typedef pointers.所以我建议不要 typedef 指针。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.