问题描述
我基本上正在开发一个程序,该程序允许您在 Linux 环境中使用 C++ 制作简单的基因图。 这是我现在编写的完整代码:genogram.h
#include <cstddef>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
namespace genogram
{
typedef string Name;
typedef char Relationship;
struct personNode; // to be defined in genogram.cpp
typedef personNode* Genogram; // a genogram is identified by the pointer to the first person entered
const Genogram emptyGenogram = nullptr;
Genogram createEmptyGenogram();
bool addPerson(Name,char,string,Genogram&);
Genogram getMother(Name,const Genogram&);
bool hasMother(Name,const Genogram&);
Genogram getFather(Name,const Genogram&);
bool hasFather(Name,const Genogram&);
Genogram getPartner(Name,const Genogram&);
bool hasPartner(Name,const Genogram&);
bool arePartners(Name,Name,const Genogram&);
bool hasSons(Name,const Genogram&);
bool isSon(Name,const Genogram&);
bool arebrothers(Name,const Genogram&);
bool areRelated(Name,const Genogram&);
bool addRelMother(Name,Genogram&);
bool addRelFather(Name,Genogram&);
bool addRelCouple(Name,Genogram&);
bool addRelChildToCouple(Name,Genogram&);
void printGenogram(Genogram);
bool deletePerson(Name,Genogram&);
}
genogram.cpp
#include "genogram.h"
using namespace genogram;
void debugg(int n)
{
cout << n << endl;
}
struct son
{
personNode* person;
son* nextSon;
};
son* emptySon = nullptr;
struct genogram::personNode
{
Name name;
char sex;
string birthDate;
string deathDate;
personNode* mother;
personNode* father;
personNode* partner;
son* linkSons;
personNode* nextPerson;
bool visited;
};
//**************************************************//
//Returns an empty Genogram
Genogram genogram::createEmptyGenogram()
{
return emptyGenogram;
}
//**************************************************//
Genogram createPerson(Name n,char sex,string bDate,string dDate)
{
personNode* p = new personNode;
p->name = n;
if(sex=='M'||sex=='F')
p->sex = sex;
else
return emptyGenogram;
p->birthDate = bDate;
p->deathDate = dDate;
p->mother = emptyGenogram;
p->father = emptyGenogram;
p->partner = emptyGenogram;
p->linkSons = emptySon;
p->visited = false;
return p;
}
son* createSon(personNode* p)
{
son* s = new son;
s->person = p;
s->nextSon = emptySon;
return s;
}
personNode* getPerson(Name n,Genogram g)
{
Genogram aux = g;
while (aux!=emptyGenogram)
{
if(aux->name==n)
return aux;
aux=aux->nextPerson;
}
return emptyGenogram;
}
bool member(Name n,Genogram g)
{
return (getPerson(n,g)!=emptyGenogram);
}
bool genogram::addPerson(Name n,string dDate,Genogram& g)
{
if(member(n,g))
return false;
Genogram aux = createPerson(n,sex,bDate,dDate);
if(aux==emptyGenogram)
return false;
aux->nextPerson = g;
g = aux;
return true;
}
//**************************************************//
Genogram genogram::getMother(Name n,const Genogram& g)
{
if(member(n,g))
return getPerson(n,g)->mother;
return emptyGenogram;
}
bool genogram::hasMother(Name n,const Genogram& g)
{
return getMother(n,g)!=emptyGenogram;
}
Genogram genogram::getFather(Name n,g)->father;
return emptyGenogram;
}
bool genogram::hasFather(Name n,const Genogram& g)
{
return getFather(n,g)!=emptyGenogram;
}
Genogram genogram::getPartner(Name n,g)->partner;
return emptyGenogram;
}
bool genogram::hasPartner(Name n,const Genogram& g)
{
return getPartner(n,g)!=emptyGenogram;
}
bool genogram::arePartners(Name n1,Name n2,const Genogram& g)
{
if(hasPartner(n1,g))
return (getPartner(n1,g)->name==n2);
else
return false;
}
son* getSonList(Name n,g)->linkSons;
return emptySon;
}
bool genogram::hasSons(Name n,const Genogram& g)
{
return getSonList(n,g)!=emptySon;
}
bool genogram::isSon(Name s,Name p,const Genogram& g)
{
if(hasSons(p,g))
{
son* sonAux = getSonList(p,g);
while(sonAux!=emptySon)
{
if(sonAux->person->name==s)
return true;
sonAux = sonAux->nextSon;
}
}
return false;
}
bool genogram::arebrothers(Name n1,const Genogram& g)
{
son* sonAux = emptySon;
if(hasMother(n1,g))
{
sonAux = getSonList(getMother(n1,g)->name,g);
while(sonAux!=emptySon)
{
if(sonAux->person->name==n2)
return true;
sonAux = sonAux->nextSon;
}
}
if(hasMother(n1,g))
{
sonAux = getSonList(getFather(n1,g);
while(sonAux!=emptySon)
{
if(sonAux->person->name==n2)
return true;
sonAux = sonAux->nextSon;
}
}
return false;
}
bool genogram::areRelated(Name n1,const Genogram& g)
{
if(hasMother(n1,g))
{
Genogram aux = getMother(n1,g);
//when here,segment. fault
if(aux->name==n2)
return true;
}
if(hasMother(n2,g))
if(getMother(n2,g)->name==n1)
return true;
if(hasFather(n1,g))
if(getFather(n1,g)->name==n2)
return true;
if(hasFather(n2,g))
if(getFather(n2,g)->name==n1)
return true;
if(arePartners(n1,n2,g))
return true;
if(isSon(n1,g))
return true;
if(isSon(n2,n1,g))
return true;
if(arebrothers(n1,g))
return true;
return false;
}
//**************************************************//
bool genogram::addRelMother(Name s,Name m,Genogram& g)
{
if(hasMother(s,g)||!member(s,g)||!member(m,g)||s==m)
return false;
personNode* aux = getPerson(s,g);
aux->mother = getPerson(m,g);
personNode* aux2 = getPerson(m,g);
son* sonAux = createSon(getPerson(s,g));
sonAux->nextSon = aux2->linkSons;
aux2->linkSons = sonAux;
return true;
}
bool genogram::addRelFather(Name s,Name f,Genogram& g)
{
if(hasFather(s,g)||!member(f,g)||s==f)
return false;
personNode* aux = getPerson(s,g);
aux->father = getPerson(f,g);
personNode* aux2 = getPerson(f,g));
sonAux->nextSon = aux2->linkSons;
aux2->linkSons = sonAux;
return true;
}
bool genogram::addRelCouple(Name n1,Genogram& g)
{
if(arePartners(n1,g))
return true;
if(areRelated(n1,g)||hasPartner(n1,g)||hasPartner(n2,g)||!member(n1,g)||!member(n2,g)||n1==n2)
return false;
personNode* aux = getPerson(n1,g);
aux->partner = getPerson(n2,g);
personNode* aux2 = getPerson(n2,g);
aux2->partner = getPerson(n1,g);
return true;
}
bool genogram::addRelChildToCouple(Name s,Genogram& g)
{
if(!arePartners(m,f,g))
return false;
return (addRelMother(s,m,g) && addRelFather(s,g));
}
//**************************************************//
void genogram::printGenogram(Genogram g)
{
Genogram aux = g;
son* sonAux = emptySon;
while (aux!=emptyGenogram)
{
cout << "-----------------\n";
cout << "Name: " << aux->name << "; sex: " << aux->sex << "; born: " << aux->birthDate << "; dead: " << aux->deathDate;
cout << ";\n - mother: ";
if(aux->mother!=emptyGenogram)
cout << aux->mother->name << ";";
cout << "\n - father: ";
if(aux->father!=emptyGenogram)
cout << aux->father->name << ";";
cout << "\n - partner: ";
if(aux->partner!=emptyGenogram)
cout << aux->partner->name << ";";
cout << "\n - sons: ";
sonAux = aux->linkSons;
if(aux->linkSons!=emptySon)
{
while(sonAux!=emptySon)
{
cout << sonAux->person->name << "; ";
sonAux = sonAux->nextSon;
}
cout << "\b\b.";
}
aux = aux->nextPerson;
cout << "\n";
}
cout << "-----------------\n";
}
//**************************************************//
bool genogram::deletePerson(Name n,Genogram& g)
{
return true;
}
然后这里是 main.cpp,我在这里做了一些测试:
#include <cstdlib>
#include <iostream>
////////////////////////////////////////////////////////////////////////
// Test main
////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include "genogram.h"
using namespace std;
int main()
{
genogram::Genogram g = genogram::createEmptyGenogram();
genogram::addPerson("Mark",'M',"25/09/2001","29/07/2020",g);
genogram::addPerson("Elizabeth",'F',"31/02/2003","-",g);
genogram::addPerson("Karl","04/03/2020",g);
genogram::addRelCouple("Elizabeth","Mark",g);
genogram::addRelMother("Karl","Elizabeth",g);
if(genogram::areRelated("Elizabeth","Karl",g)) // true)//
cout << "Test1: success" << endl;
else
cout << "Test1: no success" << endl;
if(genogram::areRelated("Karl",g))
cout << "Test2: success" << endl;
else
cout << "Test2: no success" << endl;
}
基本上,我遇到的问题是,之后我使用 addRelMother("sonName","motherName",g)
来创建儿子和母亲之间的关系,当我尝试使用函数 "sonName"
查看 "anotherName"
是否以任何方式与 areRelated("sonName","anotherName",g)
相关,会发生分段错误(核心转储)错误。更具体地说,当这个函数被执行时,它首先检查 "sonName"
是否已经使用函数 hasMother("sonName",g)
为他分配了一个母亲(它基本上只是检查函数 getMother("sonName",g)
是否返回 {{1 }},它是 nullptr 的别名,或者不是)。在 if 语句中返回 true 后,它会尝试指向母亲的名字,但即使 emptyGenogram
不返回 {{1} },如果我指向 name 字段,则会发生分段错误(核心转储)错误。
getMother("sonName",g)
有人可以帮我找出发生这种情况的原因吗?
解决方法
您的代码在这一行崩溃了:
sonAux = getSonList(getFather(n1,g)->name,g);
你可以很容易地看到 getFather() 正在返回 null:
Genogram gg = getFather(n1,g); // it is null
sonAux = getSonList(gg->name,g);
您需要简化和重构您的代码。还可以考虑使用智能指针。