【问题标题】:How do I remove this segmentation fault in my bst_insert_node function?如何在我的 bst_insert_node 函数中删除此分段错误?
【发布时间】:2018-12-26 19:09:29
【问题描述】:

我的函数 bst_insert_node() 出现分段错误。 Left 是节点的左“子”,其电话值始终小于其父节点。 Right 是节点的右“子节点”,它始终具有比其父节点更大的 phone 值。 Bst 代表二叉搜索树。我的主要功能在另一个文件中。主要问题应该是我的函数bst_insert_node()

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "introprog_telefonbuch.h"

// Adds a node with the given phone number (phone) and the name of the owner of that phone number
// into the binary search tree.

void bst_insert_node(bstree* bst, unsigned long phone, char *name) {

bst_node* new = malloc(sizeof(bst_node));
name = malloc(sizeof(char) *MAX_STR);
snprintf(name, MAX_STR, "%s",name);
new->left = NULL;
new->right = NULL;
new->parent = NULL;
new->phone = phone;

if(bst == NULL){
bst->root = new;
}

bst_node* finder = bst->root;

while(finder != NULL){
if(finder->phone == phone){
  printf("This phone number already exist");
  return;
}
if(phone < finder->phone){
  if(finder->left == NULL){
    new->parent = finder;
    finder->left = new;
    return;
  }
  finder = finder->left;
}


if(phone > finder->phone){
  if(finder->right == NULL){
    new->parent = finder;
    finder->right = new;
    return;
  }

  finder = finder->right;
}
}
}

// This function returns a pointer that points to the node that contains the phone
// number that is being searched. If such a phone number is non existent,
// you return NULL.
bst_node* find_node(bstree* bst, unsigned long phone) {

bst_node* finder = bst->root;

while(finder != NULL){                       

if(finder->phone == phone){ 
    return finder;
}

if(finder->phone > phone){
    finder = finder->left;
}  
else{
    finder = finder->right;
} 

 }
  return NULL;
}

// print a sub-tree in "in-order" order
void bst_in_order_walk_node(bst_node* node) {

if (node == NULL){
return;
}

else{
bst_in_order_walk_node(node->left);
print_node(node);
bst_in_order_walk_node(node->right);
}
}

// the same as bst_in_order_walk_node just that you do it for the whole tree.
void bst_in_order_walk(bstree* bst) {
    if (bst != NULL) {
        bst_in_order_walk_node(bst->root);
}
}

// deletes the all sub-tree of node
void bst_free_subtree(bst_node* node) {
    if(node == NULL){
        return;
 }
 else{
    bst_free_subtree(node->left);
    bst_free_subtree(node->right);
    free(node->name);
    free(node);
 }
 }

 // Deletes the whole tree
 void bst_free_tree(bstree* bst) {
    if(bst != NULL && bst->root != NULL) {
        bst_free_subtree(bst->root);
        bst->root = NULL;
}
}

下面是main函数和接口函数:

// Kreiert eine Benutzeroberfläche
bstree* interface(bstree *bst) {
    help();
    char *operation;
    unsigned long phone;
    char *name;
    read_line_context in;
    open_stdin(&in);
    printf("> ");
    while (read_line(&in, &operation, &phone, &name) == 0) {
        if (operation != NULL) {
            if (operation[0] == '?' && phone > 0) {
                find_and_print(bst, phone);
            } else if (operation[0] == '+' && phone > 0 && strlen(name) > 0) {    
                bst_insert_node(bst, phone, name);
            } else if (operation[0] == 'd') {
                debug(bst);
            } else if (operation[0] == 'p') {
                bst_in_order_walk(bst);
            } else if (operation[0] == 'q') {
                break;
            } else {
                printf("Inkorrekte Eingabe\n\n");
                help();
            }
        }
        printf("> ");
        phone = -1;
    }
    printf("Exiting...\n");
    close_file(&in);
    return bst;
    }

int main(int argc, char** argv) {
    // Create an empty search tree
    bstree bst;
    bst.root = NULL;
    bst.count = 0;

    if (argc != 2)
    {
        printf("Nutzung: %s <Dateiname>\n",argv[0]);
        return 1;
    }

    // reading the txt file
    read_file(argv[1], &bst);

    // creating the interface
    interface(&bst);

    bst_free_tree(&bst);

    return 0;
    }

该程序应该获取一个包含所有电话号码和姓名的文本文件,并将其放入二叉搜索树中。我的程序正在编译,但由于某种原因,当我按“p”(按 p 应该显示“按顺序”排序的电话号码)时,没有电话号码出现,程序只是再次等待另一个输入。

【问题讨论】:

  • 一个好的开始是learn how to debug your programs
  • 此外,最好了解name = malloc(sizeof(char) *MAX_STR) 后跟snprintf(name, MAX_STR, "%s",name) 会发生什么。顺便说一下,后者是明确的undefined behavior
  • if(bst == NULL){ bst-&gt;root = new; }太棒了!
  • 另外,在到达应该在的叶子之前不要分配新节点。然后,当您分配它时,将其返回,以便通过将结果分配给父级中的左侧或右侧,将其链接到树中。

标签: c segmentation-fault binary-tree binary-search-tree


【解决方案1】:

这里有一个可能的段错误:

if(bst == NULL){
    bst->root = new;
}

你不能为 bst 的成员分配任何东西,因为它是空的。也许你打算在这里建造一个新的 BST?其他一些注意事项...

  • 就我个人而言,我会避免使用标记 new,因为它会让 C++ 程序员感到困惑。
  • 应该检查 malloc 的结果以防它失败,但更重要的是 snprintf() 不应该写入它正在读取的缓冲区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 2021-01-08
    • 2021-12-11
    • 2012-09-19
    • 1970-01-01
    相关资源
    最近更新 更多