In: Computer Science
lineage program to Memheck-clean. The program is a simplified family tree manager. It maintains a list of Persons in a PersonList. Each Person object maintains a set of pointers to his/her parents as well as to his/her children. The code contains several memory leaks. To compile:
please highlight the changes
$g++ -g -O0 -fno-inline *.cpp -o lineage
code
linage.cpp
// Adapted from
http://people.cs.ksu.edu/~sherrill/labs/lab05/lineage.cpp
#include "person.h"
#include "personList.h"
int main() {
    PersonList theList;
    theList.addPerson("Bob", "Mark",
"Betty");
    theList.addPerson("Jim", "Bob", "Sally");
    theList.addPerson("Frank", "Jim", "Mary");
    theList.addPerson("Leonard", "Jim",
"Mary");
    theList.addPerson("Kim", "Leonard",
"Sarah");
    theList.printLineage("Jim");
    theList.printLineage("Kim");
    theList.printLineage("Betty");
    return 0;
}
/* Output (your revised solution should give the same
output)
Ancestors of Jim
mother: Sally
father: Bob
grand mother: Betty
grand father: Mark
Decendents of Jim
child: Frank
child: Leonard
grand child: Kim
Ancestors of Kim
mother: Sarah
father: Leonard
grand mother: Mary
grand father: Jim
great grand mother: Sally
great grand father: Bob
great great grand mother: Betty
great great grand father: Mark
Decendents of Kim
Ancestors of Betty
Decendents of Betty
child: Bob
grand child: Jim
great grand child: Frank
great grand child: Leonard
great great grand child: Kim
*/
person.cpp
#include "person.h"
#include
#include
using std::cout;
using std::endl;
Person::Person(char *name, Person* father, Person*
mother){
    this->name = new char[strlen(name)];
    strcpy(this->name, name);
    this->father = father;
    this->mother = mother;
    capacity = 1;
    numChildren = 0;
    children = new Person*[capacity];
}
Person::~Person(){
    delete children;
}
void Person::addChild(Person *newChild){
    if(numChildren == capacity)
expand(&children, &capacity);
    children[numChildren++] = newChild;
}
void Person::printAncestors(){
    cout << endl << "Ancestors of "
<< name << endl;
    printLineage('u', 0);
}
void Person::printDecendents(){
    cout << endl << "Decendents of "
<< name << endl;
    printLineage('d', 0);
}
void Person::printLineage(char dir, int level){
    char *temp = compute_relation(level);
    if(dir == 'd'){
        for(int i = 0; i <
numChildren; i++){
           
cout << temp << "child: " <<
children[i]->getName() << endl;
           
children[i]->printLineage(dir, level + 1);
        }
    } else {
        if(mother){
           
cout << temp << "mother: " <<
mother->getName() << endl;
           
mother->printLineage(dir, level + 1);
        }
        if(father){
           
cout << temp << "father: " <<
father->getName() << endl;
           
father->printLineage(dir, level + 1);
        }
    }
}
/* helper function to compute the lineage
* if level = 0 then returns the empty string
* if level >= 1 then returns ("great ")^(level - 1) + "grand
"
*/
char* Person::compute_relation(int level){
    if(level == 0) return strcpy(new char[1],
"");
    char *temp = strcpy(new char[strlen("grand ")
+ 1], "grand ");;
  
    for(int i = 2; i <= level; i++){
        char *temp2 = new
char[strlen("great ") + strlen(temp) + 1];
        strcat(strcpy(temp2,
"great "), temp);
        temp = temp2;
    }
    return temp;
}
/* non-member function which doubles the size of t
* NOTE: t's type will be a pointer to an array of pointers
*/
void expand(Person ***t, int *MAX){
Person **temp = new Person*[2 * *MAX];
memcpy(temp, *t, *MAX * sizeof(**t));
*MAX *= 2;
*t = temp;
}
person.h
#ifndef __PERSON_H__
#define __PERSON_H__
class Person{
    private:
        char *name;
        Person *father; //
pointer to the father
        Person *mother; //
pointer to the mother
        Person **children; //
array of pointers to the kids
        int numChildren; //
number of kids in children array
        int capacity; //
capacity of children array
    public:
        Person(char *name,
Person* father, Person* mother);
        ~Person();
const char* getName(){return name;}
void addChild(Person *newChild);
        void
printAncestors();
        void
printDecendents();
    private:
        void printLineage(char
dir, int level);
        /* helper function to
compute the lineage
         * if level = 0
then returns the empty string
         * if level >= 1
then returns ("great ")^(level - 1) + "grand "
         */
        char*
compute_relation(int level);
};
/* non-member function which doubles the size of t
* NOTE: t's type will be a pointer to an array of pointers
*/
void expand(Person ***t, int *MAX);
#endif // __PERSON_H__
personList.cpp
#include "personList.h"
#include
#include
using std::cout;
using std::endl;
PersonList::PersonList(){
    capacity = 2;
    numPeople = 0;
    theList = new Person*[capacity];
}
PersonList::~PersonList(){
    delete [] theList;
}
void PersonList::addPerson(char* child_name, char* father_name,
char* mother_name){
    Person *father = 0;
    Person *mother = 0;
  
    // try to find the three names in the
theList
    for(int i = 0; i < numPeople; i++){
       
if(!strcmp(theList[i]->getName(), child_name)){
           
cout << "ERROR: " << child_name << " already has
parents!!!";
           
return;
        } else
if(!strcmp(theList[i]->getName(), father_name)) {
           
father = theList[i];
        } else
if(!strcmp(theList[i]->getName(), mother_name)) {
           
mother = theList[i];
        }
    }
    if(father == 0){
      // father_name is not in the theList
so create a new person
      father = new Person(father_name, 0,
0);
      insertIntoList(father);
    }
    if(mother == 0){
      // mother_name is not in the theList
so create a new person
      mother = new Person(mother_name, 0,
0);
      insertIntoList(mother);
    }
    Person *newChild = new Person(child_name,
father, mother);
    insertIntoList(newChild);
    father->addChild(newChild);
    mother->addChild(newChild);
}
void PersonList::insertIntoList(Person *newPerson){
    if(numPeople == capacity) expand(&theList,
&capacity);
    theList[numPeople++] = newPerson;
}
void PersonList::printLineage(char* person){
    for(int i = 0; i < numPeople; i++) {
       
if(!strcmp(theList[i]->getName(), person)){
           
theList[i]->printAncestors();
           
theList[i]->printDecendents();
           
return;
        }
    }
    cout << endl << person << " is
not in the list!" << endl;
}
personList.h
#ifndef __PERSONLIST_H__
#define __PERSONLIST_H__
#include "person.h"
class PersonList{
    private:
      Person **theList; // array of
pointers to person objects
      int numPeople; // current number of
people in theList
      int capacity; // capacity of theList
array
    public:
        PersonList();
        ~PersonList();
        void addPerson(char*
child_name, char* father_name, char* mother_name);
        void
insertIntoList(Person *newPerson);
        void printLineage(char*
person);
};
#endif // __PERSONLIST_H__
// LINAGE.CPP
// Adapted from http://people.cs.ksu.edu/~sherrill/labs/lab05/lineage.cpp
#include "person.h"
#include "personList.h"
int main() {
    PersonList theList;
    theList.addPerson("Bob", "Mark", "Betty");
    theList.addPerson("Jim", "Bob", "Sally");
    theList.addPerson("Frank", "Jim", "Mary");
    theList.addPerson("Leonard", "Jim", "Mary");
    theList.addPerson("Kim", "Leonard", "Sarah");
    theList.printLineage("Jim");
    theList.printLineage("Kim");
    theList.printLineage("Betty");
    return 0;
}
/* Output (your revised solution should give the same output)
Ancestors of Jim
mother: Sally
father: Bob
grand mother: Betty
grand father: Mark
Decendents of Jim
child: Frank
child: Leonard
grand child: Kim
Ancestors of Kim
mother: Sarah
father: Leonard
grand mother: Mary
grand father: Jim
great grand mother: Sally
great grand father: Bob
great great grand mother: Betty
great great grand father: Mark
Decendents of Kim
Ancestors of Betty
Decendents of Betty
child: Bob
grand child: Jim
great grand child: Frank
great grand child: Leonard
great great grand child: Kim
*/
// PERSON.CPP
#include "person.h"
#include<iostream>
#include<string.h>
using std::cout;
using std::endl;
Person::Person(const char *name, Person* father, Person* mother){
    this->name = new char[strlen(name)];
    strcpy(this->name, name);
    this->father = father;
    this->mother = mother;
    capacity = 1;
    numChildren = 0;
    children = new Person*[capacity];
}
Person::~Person(){
    delete children;
    delete name;
}
void Person::addChild(Person *newChild){
    if(numChildren == capacity) expand(&children, &capacity);
    children[numChildren++] = newChild;
}
void Person::printAncestors(){
    cout << endl << "Ancestors of " << name << endl;
    printLineage('u', 0);
}
void Person::printDecendents(){
    cout << endl << "Decendents of " << name << endl;
    printLineage('d', 0);
}
void Person::printLineage(char dir, int level){
    char *temp = compute_relation(level);
    if(dir == 'd'){
        for(int i = 0; i < numChildren; i++){
            cout << temp << "child: " << children[i]->getName() << endl;
            children[i]->printLineage(dir, level + 1);
        }
    } else {
        if(mother){
            cout << temp << "mother: " << mother->getName() << endl;
            mother->printLineage(dir, level + 1);
        }
        if(father){
            cout << temp << "father: " << father->getName() << endl;
            father->printLineage(dir, level + 1);
        }
    }
}
/* helper function to compute the lineage
* if level = 0 then returns the empty string
* if level >= 1 then returns ("great ")^(level - 1) + "grand "
*/
char* Person::compute_relation(int level){
    if(level == 0) return strcpy(new char[1], "");
    char *temp = strcpy(new char[strlen("grand ") + 1], "grand ");;
  
    for(int i = 2; i <= level; i++){
        char *temp2 = new char[strlen("great ") + strlen(temp) + 1];
        strcat(strcpy(temp2, "great "), temp);
        temp = temp2;
        delete[] temp2;   // change
    }
    return temp;
}
/* non-member function which doubles the size of t
* NOTE: t's type will be a pointer to an array of pointers
*/
void expand(Person ***t, int *MAX){
    Person **temp = new Person*[2 * *MAX];
    memcpy(temp, *t, *MAX * sizeof(**t));
    delete[] *t;   // change
    *MAX *= 2;
    *t = temp;
}
// PERSONLIST.CPP
#include "personList.h"
#include<iostream>
#include<string.h>
using std::cout;
using std::endl;
PersonList::PersonList(){
    capacity = 2;
    numPeople = 0;
    theList = new Person*[capacity];
}
PersonList::~PersonList(){
    delete [] theList;
}
void PersonList::addPerson(const char* child_name, const char* father_name, const char* mother_name){
    Person *father = 0;
    Person *mother = 0;
  
    // try to find the three names in the theList
    for(int i = 0; i < numPeople; i++){
        if(!strcmp(theList[i]->getName(), child_name)){
            cout << "ERROR: " << child_name << " already has parents!!!";
            return;
        } else if(!strcmp(theList[i]->getName(), father_name)) {
            father = theList[i];
        } else if(!strcmp(theList[i]->getName(), mother_name)) {
            mother = theList[i];
        }
    }
    if(father == 0){
      // father_name is not in the theList so create a new person
      father = new Person(father_name, 0, 0);
      insertIntoList(father);
    }
    if(mother == 0){
      // mother_name is not in the theList so create a new person
      mother = new Person(mother_name, 0, 0);
      insertIntoList(mother);
    }
    Person *newChild = new Person(child_name, father, mother);
    insertIntoList(newChild);
    father->addChild(newChild);
    mother->addChild(newChild);
}
void PersonList::insertIntoList(Person *newPerson){
    if(numPeople == capacity) expand(&theList, &capacity);
    theList[numPeople++] = newPerson;
}
void PersonList::printLineage(const char* person){
    for(int i = 0; i < numPeople; i++) {
        if(!strcmp(theList[i]->getName(), person)){
            theList[i]->printAncestors();
            theList[i]->printDecendents();
            return;
        }
    }
    cout << endl << person << " is not in the list!" << endl;
}
// PERSON.H
#ifndef __PERSON_H__
#define __PERSON_H__
class Person{
    private:
        char *name;
        Person *father; // pointer to the father
        Person *mother; // pointer to the mother
        Person **children; // array of pointers to the kids
        int numChildren; // number of kids in children array
        int capacity; // capacity of children array
    public:
        Person(const char *name, Person* father, Person* mother);
        ~Person();
        const char* getName(){return name;}
        void addChild(Person *newChild);
        void printAncestors();
        void printDecendents();
    private:
        void printLineage( char dir, int level);
        /* helper function to compute the lineage
         * if level = 0 then returns the empty string
         * if level >= 1 then returns ("great ")^(level - 1) + "grand "
         */
        char* compute_relation(int level);
};
/* non-member function which doubles the size of t
* NOTE: t's type will be a pointer to an array of pointers
*/
void expand(Person ***t, int *MAX);
#endif // __PERSON_H__
// PERSONLIST.H
#ifndef __PERSONLIST_H__
#define __PERSONLIST_H__
#include "person.h"
class PersonList{
    private:
      Person **theList; // array of pointers to person objects
      int numPeople; // current number of people in theList
      int capacity; // capacity of theList array
    public:
        PersonList();
        ~PersonList();
        void addPerson(const char* child_name, const char* father_name, const char* mother_name);
        void insertIntoList(Person *newPerson);
        void printLineage(const char* person);
};
#endif // __PERSONLIST_H__
just copy all the code into respective files.
***** ensure that code is copied correctly *******
command to run
g++ linage.cpp person.cpp personList.cpp
./a.out
