[英]Segmentation Fault error - binary search tree in C
我正在嘗試構建二叉搜索樹。 使用插入 function 插入 integer(僅使用 1 到 100 進行測試)並使用中序遍歷將結果附加到文件中。 但是,我遇到了分段錯誤錯誤。 在 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*
我在這里做錯了什么? :(
您將BST
聲明為:
typedef struct node *BST;
所以,它是一個指向struct node
的指針,你的問題可能在這里:
temp = *(BST *)malloc(sizeof(BST));
您正在分配 memory 但您指定的字節大小是BST
的字節大小,即指向struct node
的指針,而您要分配一個struct node
。
您將malloc
的返回值轉換為指向BST
的指針,即指向struct node
的指針的指針。 然后您取消引用它以將結果分配給temp
。 因此,您分配給temp
的是指向struct node
的指針(正確),但指向的 object 的大小錯誤。 無論如何, 您不應該malloc
( void *
) 返回的值。
事情比你想象的要簡單得多:如果你想分配一個struct node
(或其他任何東西),請將其大小傳遞給malloc
。 malloc
返回一個指向已分配struct node
的void *
指針,您可以將其分配給任何指針變量而無需強制轉換。
注意:您應該檢查返回的值,因為如果malloc
失敗,它會返回NULL
並且您不應該使用它。
試試這個,而不是:
temp = malloc(sizeof (struct node));
if(temp == NULL) {
fprintf(stderr, "%s:%d allocation failed\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
我假設在您的情況下分配錯誤是不可恢復的,如果是,請調整。
注意:您也可以按照評論中的建議使用:
temp = malloc(sizeof *temp);
通過施工,這將始終有效。 但只要您對指針和 memory 分配不完全滿意,我建議您使用帶有malloc
的顯式類型。 它更容易閱讀和理解,即使它不太容易維護(如果你更改temp
的類型)。
但是您的代碼還有其他問題。 您的insert
和find
功能是偽造的。 理解為什么留作調試練習。
主要問題在於此聲明:
temp = *(BST *)malloc(sizeof(BST));
正如其他答案中已經清楚解釋的那樣,我將跳過它。
所以你可以這樣做:
temp = malloc(sizeof (struct node));
或者
// to add : this helps in case the type of temp ever changes,
temp = malloc(sizeof(*temp));
其他小的邏輯變化:
find
function中,不需要這個else if
語句 // = or == doesn't matter now
else (root->data = number);
insert
function 中,您忘記鏈接在根節點之后插入的節點。 因此,每當您執行中inorder traversal
時,您只會得到根節點,即0
在您的情況下。筆記:
typedef
用於使代碼更具可讀性,但使用 typedef 隱藏指針會造成混亂。 所以我建議不要 typedef 指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.