簡體   English   中英

分段錯誤錯誤 - C 中的二叉搜索樹

[英]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));
  1. 您正在分配 memory 但您指定的字節大小是BST的字節大小,即指向struct node的指針,而您要分配一個struct node

  2. 您將malloc的返回值轉換為指向BST的指針,即指向struct node的指針的指針。 然后您取消引用它以將結果分配給temp 因此,您分配給temp的是指向struct node的指針(正確),但指向的 object 的大小錯誤。 無論如何, 您不應該malloc ( void * ) 返回的值

事情比你想象的要簡單得多:如果你想分配一個struct node (或其他任何東西),請將其大小傳遞給malloc malloc返回一個指向已分配struct nodevoid *指針,您可以將其分配給任何指針變量而無需強制轉換。

注意:您應該檢查返回的值,因為如果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的類型)。

但是您的代碼還有其他問題。 您的insertfind功能是偽造的。 理解為什么留作調試練習。

主要問題在於此聲明:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM