实现家谱时出现 C++ 核心转储错误
C++ core dump error while implementing family tree
我正在尝试实现家谱。我有 类 Person
和 Tree
定义如下:
文件FamilyTree.hpp
:
using namespace std;
#include <string>
namespace family{
class Person{
public:
string name;
Person* mother;
Person* father;
Person(string name);
};
class Tree{
public:
Person* root;
Tree(string name);
Tree& addFather(string name1, string name2);
Tree addMother(string name1, string name2);
void display();
string relation(string name);
string find(string name);
void remove(string name);
};
};
文件FamilyTree.cpp
:
#include "FamilyTree.hpp"
#include <string>
#include <iostream>
using namespace family;
// FUNCTIONS
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
cout<<root.name<<":1"<<endl;
findPerson(*root.father, child_name);
}
else if(root.name.compare(child_name) == 0){
cout<<root.name<<":2"<<endl;
return root;
}else{
cout<<"not found!!!"<<endl;
Person p("no found");
return p;
}
}
// PERSON
family::Person::Person(string person_name){
name = person_name;
father = nullptr;
mother = nullptr;
};
// TREE
family::Tree::Tree(string name){
root = new Person(name);
};
family::Tree& Tree::addFather(string child, string father){
Person& child_found = findPerson(*root, child);
//cout<<"child_found.name:"<<child_found.name<<endl;
child_found.father = new Person(father);
return *this;
};
family::Tree family::Tree::addMother(string name1, string name2){return Tree("");};
void family::Tree::display(){};
string family::Tree::relation(string name){return "";};
string family::Tree::find(string name){return "";};
void family::Tree::remove(string name){};
int main(){
Tree t("X");
t.addFather("X", "Y");
t.addFather("Y","Z");
return 0;
}
我从 addFather()
函数开始:
addFather("child", "new father")
为现有 child 添加新父亲。
我使用 findPerson()
函数递归实现它,其中 returns Person
object 用于 child 和 addFather()
函数创建新的 Person
并将其初始化以找到 child.
添加2个父亲后,出现Illegal instruction (core dumped)错误,请问是什么问题?
如果您打开警告,您会发现您并不总是 return来自 findPerson
。在这个函数中
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
cout<<root.name<<":1"<<endl;
findPerson(*root.father, child_name); // (1)
}
else if(root.name.compare(child_name) == 0){
cout<<root.name<<":2"<<endl;
return root;
}else{
cout<<"not found!!!"<<endl;
Person p("no found");
return p; // (2)
}
}
第一个 if
分支中的代码,标记为 (1)
,需要 return 递归找到的人,像这样
return findPerson(*root.father, child_name);
这应该可以解决段错误。
但是,在该函数的最后一个分支中存在更深层次的问题,您在此处 return 引用局部变量 p
,标记为 (2)
。如果你这样做,你就是 return 悬空引用,因为当函数 returns.
时 p
将超出范围
你要想想这个函数在没有找到Person的情况下应该做什么。
你可能会 return 一个 Person*
,所以 nullptr
意味着找不到人。
你可以 return 一个 std::optional<Person>
。
问题是您不能 return 对本地对象的引用。这将导致未定义的行为。
当你添加一个新成员时,findPerson()
将不会尝试return 找到它这样的本地对象p。这是注定要失败的。
这个设计不是最优的。可能的解决方案:
- 声明一个静态对象 p,当没有找到时 returned。与局部变量不同,static 仍然有效,然后引用 returned 将保持有效。但是,您必须确保绝不会以可能更改静态对象名称的方式使用此 returned 引用。
- 更改
findPerson()
的接口,使其 return 指针。它要么 return 是指向某个人的有效指针,要么 return 是 nullptr
如果找不到任何东西。这是一个常见的习惯用法(在现实世界的开发中,你会 return 一个迭代器,但如果你是从 C++ 开始,这暂时就太复杂了)。
- 如果未找到任何内容,则抛出异常并重写调用代码以捕获异常。我不建议在这里使用这种方法:在真正特殊的情况下最好保留例外。
请注意,如果还有其他错误,我没有查看您的代码。我只是在第一次尝试寻找当树为空时不存在的东西时停下来。
它适用于父亲搜索,但我需要它来遍历整个树。
当我加了mothers root的时候,它又核心转储了。
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
//cout<<root.name<<":1"<<endl;
return findPerson(*root.father, child_name);
return findPerson(*root.mother, child_name); // (1)
}
else if(root.name.compare(child_name) == 0){
//cout<<root.name<<":2"<<endl;
return root;
}else{
throw exception();
}
}
我正在尝试实现家谱。我有 类 Person
和 Tree
定义如下:
文件FamilyTree.hpp
:
using namespace std;
#include <string>
namespace family{
class Person{
public:
string name;
Person* mother;
Person* father;
Person(string name);
};
class Tree{
public:
Person* root;
Tree(string name);
Tree& addFather(string name1, string name2);
Tree addMother(string name1, string name2);
void display();
string relation(string name);
string find(string name);
void remove(string name);
};
};
文件FamilyTree.cpp
:
#include "FamilyTree.hpp"
#include <string>
#include <iostream>
using namespace family;
// FUNCTIONS
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
cout<<root.name<<":1"<<endl;
findPerson(*root.father, child_name);
}
else if(root.name.compare(child_name) == 0){
cout<<root.name<<":2"<<endl;
return root;
}else{
cout<<"not found!!!"<<endl;
Person p("no found");
return p;
}
}
// PERSON
family::Person::Person(string person_name){
name = person_name;
father = nullptr;
mother = nullptr;
};
// TREE
family::Tree::Tree(string name){
root = new Person(name);
};
family::Tree& Tree::addFather(string child, string father){
Person& child_found = findPerson(*root, child);
//cout<<"child_found.name:"<<child_found.name<<endl;
child_found.father = new Person(father);
return *this;
};
family::Tree family::Tree::addMother(string name1, string name2){return Tree("");};
void family::Tree::display(){};
string family::Tree::relation(string name){return "";};
string family::Tree::find(string name){return "";};
void family::Tree::remove(string name){};
int main(){
Tree t("X");
t.addFather("X", "Y");
t.addFather("Y","Z");
return 0;
}
我从 addFather()
函数开始:
addFather("child", "new father")
为现有 child 添加新父亲。
我使用 findPerson()
函数递归实现它,其中 returns Person
object 用于 child 和 addFather()
函数创建新的 Person
并将其初始化以找到 child.
添加2个父亲后,出现Illegal instruction (core dumped)错误,请问是什么问题?
如果您打开警告,您会发现您并不总是 return来自 findPerson
。在这个函数中
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
cout<<root.name<<":1"<<endl;
findPerson(*root.father, child_name); // (1)
}
else if(root.name.compare(child_name) == 0){
cout<<root.name<<":2"<<endl;
return root;
}else{
cout<<"not found!!!"<<endl;
Person p("no found");
return p; // (2)
}
}
第一个 if
分支中的代码,标记为 (1)
,需要 return 递归找到的人,像这样
return findPerson(*root.father, child_name);
这应该可以解决段错误。
但是,在该函数的最后一个分支中存在更深层次的问题,您在此处 return 引用局部变量 p
,标记为 (2)
。如果你这样做,你就是 return 悬空引用,因为当函数 returns.
p
将超出范围
你要想想这个函数在没有找到Person的情况下应该做什么。
你可能会 return 一个
Person*
,所以nullptr
意味着找不到人。你可以 return 一个
std::optional<Person>
。
问题是您不能 return 对本地对象的引用。这将导致未定义的行为。
当你添加一个新成员时,findPerson()
将不会尝试return 找到它这样的本地对象p。这是注定要失败的。
这个设计不是最优的。可能的解决方案:
- 声明一个静态对象 p,当没有找到时 returned。与局部变量不同,static 仍然有效,然后引用 returned 将保持有效。但是,您必须确保绝不会以可能更改静态对象名称的方式使用此 returned 引用。
- 更改
findPerson()
的接口,使其 return 指针。它要么 return 是指向某个人的有效指针,要么 return 是nullptr
如果找不到任何东西。这是一个常见的习惯用法(在现实世界的开发中,你会 return 一个迭代器,但如果你是从 C++ 开始,这暂时就太复杂了)。 - 如果未找到任何内容,则抛出异常并重写调用代码以捕获异常。我不建议在这里使用这种方法:在真正特殊的情况下最好保留例外。
请注意,如果还有其他错误,我没有查看您的代码。我只是在第一次尝试寻找当树为空时不存在的东西时停下来。
它适用于父亲搜索,但我需要它来遍历整个树。 当我加了mothers root的时候,它又核心转储了。
Person& findPerson(Person& root, string child_name){
if (root.name.compare(child_name) != 0)
{
//cout<<root.name<<":1"<<endl;
return findPerson(*root.father, child_name);
return findPerson(*root.mother, child_name); // (1)
}
else if(root.name.compare(child_name) == 0){
//cout<<root.name<<":2"<<endl;
return root;
}else{
throw exception();
}
}