0

我编写了一个 C++ 代码来构建二叉搜索树。代码编译正确,但是当我尝试运行可执行文件时,它给出了分段错误。下面是我的代码:

    #include <iostream>

using namespace std;

struct Node{
    Node *parent, *right, *left; 
    int data;
};

class bst{
    private:
    Node* root;

    public:
        bst (int data);
        void insert (Node * node, int data);
        void insert (int data);
        Node * search (int data);
        Node * search (Node * node, int data);
        // remove (Node * node, int data);
};

bst::bst (int data){
    root -> data = data;
}

void bst::insert (Node * node, int data){
    if (node == NULL){
        node -> data = data;
    }
    else if (data < node -> data){
        insert (node -> left, data);
    }
    else if (data > node -> data){
        insert (node -> right, data);
    }
}

void bst::insert (int data){
    insert (root, data);
}

Node * bst::search (Node * node, int data){
    if (node == NULL || node -> data == data)
        return node;
    else if (data < node -> data)
        return search (node -> left, data);
    else if (data > node -> data)
        return search (node -> right, data);
}

Node * bst::search (int data){
    search (root, data);
}

int main(){
    cout << "main entry\n";
    bst __bst (10);
    cout << "new causing problem\n";
    bst bst2(1);
//  bst *my_bst = new bst(10);
    cout << "tree created\n";
/*  my_bst -> insert(32);
    my_bst -> insert(3);
    my_bst -> insert(36);
    my_bst -> insert(93);
    my_bst -> insert(23);
    cout << "insertion completed\n";

    if (my_bst -> search(4) == NULL )
        cout << "4 does not exist\n";
    if (my_bst -> search(36) != NULL)
        cout << "36 exists in tree\n";
*/  return 0;
}

在调试问题时,我发现了一个有趣的观察结果。当 main 函数只包含bst 时 __bst(10); 对象定义和“新引起的问题\n”注释之后,它不会打印任何内容。所以我假设第一个对象定义引起了问题。但是当我把bst bst2(1); bst *my_bst = new bst(10); 总的来说,分段错误再次发生,但在打印“新导致问题\n”之前不会发生。所以执行确实达到了这一点。所以第一个对象定义在这种情况下没有引起任何问题。

有人可以说出导致分段错误的原因以及为什么会发生这种奇怪的事情。

编辑: 正如你们所有人指出的那样,我试图在构造函数代码期间取消引用 NULL 指针,我做了建议的更改并且代码运行良好。但是我有一个类似的程序,即使没有这些更改也能正常工作。下面是代码:

#include <iostream>

using namespace std;

struct Name{
    string first_name;
    string last_name;
};

class Person{
    public:
    Person (string first_name, string last_name){
            name -> first_name = first_name;
            name -> last_name = last_name;
    }   

    int get_age(){
            return age;
    }   

    void set_age (int new_age){
            age = new_age;
    }   

    string get_first_name(){
            return name -> first_name;
    }   

    string get_last_name(){
            return name -> last_name;
    }   

    private:
    Name * name;
    int age;
};

int main (){ 
    Person prince ("Prince", "Kumar");
    cout << prince.get_first_name() << endl;
    cout << prince.get_age() << endl;
    return 0;
}

在这种情况下,程序运行得非常好。是否为指针Name分配了一些空间的默认构造函数。name我知道它将 0 值分配给数字类型,将 NULL 分配给指针、对象和字符串。我对吗?

4

3 回答 3

0
private:
    Node* root;

root 没有在构造函数中初始化

bst::bst (int data){
    root -> data = data;
}
于 2013-04-15T09:27:03.547 回答
0

您在insert()当树为空的情况下取消引用空指针

于 2013-04-15T09:27:16.110 回答
0

在您的构造函数中,您正在取消引用作为指针的根而不为其分配任何内存,这是未定义的行为

bst::bst (int data){
  root -> data = data;
}

这样的事情就足够了:对于这个问题

bst::bst (int data) : root( new Node ) 
                      ^^^^^^^^^^^^^^^^ 
{
  root -> data = data;
}

只需使用初始化列表来分配内存。你的insert方法也有同样的问题:

if (node == NULL){
    node -> data = data;
}

解决方案类似:

node = new Node ;
node->data = data ;

尽管您需要正确地进行初始化right,但要使其正常工作leftparent我建议Node为此使用构造函数:

Node() : parent(NULL), right(NULL), left(NULL) {}

这些修复程序似乎可以为您提供一个工作程序。

于 2013-04-15T09:28:12.307 回答