二分探索木を構築する 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 を割り当てることを知っていました。私は正しいですか?