Question

In: Computer Science

lineage program to Memheck-clean. The program is a simplified family tree manager. It maintains a list...

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__

Solutions

Expert Solution



// 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


Related Solutions

1-a)List the defining characteristics of the Chondrichthyes. b) Draw a simplified phylogenetic tree for cartilaginous fishes...
1-a)List the defining characteristics of the Chondrichthyes. b) Draw a simplified phylogenetic tree for cartilaginous fishes and outline the characteristics of the three main types. 2- Describe the main evolutionary steps involved in the conquest of landmasses by vertebrate organisms during the Devonian period.
C++ tree program (do NOT use STRUCT, use classes)    Program 1 Implement a Binary tree...
C++ tree program (do NOT use STRUCT, use classes)    Program 1 Implement a Binary tree using an array    Program 2 Implement a tree using linked list - pointer Binary Tree    Program 3 - Convert program 1 to a template
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell walls. In 1990, the concentration of calcium in precipitation in a certain area was 0.11 milligrams per liter (mg/L). A random sample of 10 precipitation dates in 2007 results in the following data table. Data: 0.068 0.084 0.059 0.278 0.117 0.172 0.109 0.218 0.337 0.092 Complete parts (a) through (c) below. (a) State the hypotheses for determining if the mean concentration of calcium precipitation...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell walls. In​ 1990, the concentration of calcium in precipitation in a certain area was 0.12 0.12 milligrams per liter​ (mg/L). A random sample of 10 precipitation dates in 2007 results in the following data table. Complete parts​ (a) through​ (c) below. LOADING... Click the icon to view the data table. ​(a) State the hypotheses for determining if the mean concentration of calcium precipitation has...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell walls. In​ 1990, the concentration of calcium in precipitation in a certain area was 0.15 milligrams per liter​ (mg/L). A random sample of 10 precipitation dates in 2007 results in the following data table Complete parts​ (a) through​ (c) below (a) State the hypotheses for determining if the mean concentration of calcium precipitation has changed since 1990. ​(b) Construct a 99​% confidence interval about...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell...
Calcium is essential to tree growth because it promotes the formation of wood and maintains cell walls. In 1990, the concentration of calcium in precipatation in a certain area was 0.12 milligrams per liter. A random sample of 10 precipitation dates in 2007 results in the following: 0.079, 0.179, 0.078, 0.132, 0.074, 0.225, 0.262, 0.339. 0.111, 0.119 Construct a 98% confidence interval about the sample mean concentration of calcium precipitation. A- State the hypothesis B- test statistic?? C- P value...
You have been hired to produce a family tree for three generations of a family where...
You have been hired to produce a family tree for three generations of a family where a disorder called sneezer syndrome is observed. People who suffer from sneezer syndrome sneeze when they smell peppermint. In order to draw a pedigree chart for this family, you interview Mike and Annie. Neither suffer from sneezer syndrome. Annie’s mother is normal, while Annie’s father sneezed at the smell of peppermint. Annie has one sister and one brother and her sister is a sneezer....
Traversal tree program in c/c++
Traversal tree program in c/c++
An excellent example of a program that can be greatly simplified by the use of recursion...
An excellent example of a program that can be greatly simplified by the use of recursion is the Chapter 4 case study, escaping a maze. As already explained, in each maze cell the mouse stores on the maze stack up to four cells neighboring the cell in which it is currently located. The cells put on the stack are the ones that should be investigated after reaching a dead end. It does the same for each visited cell. Write a...
/** * This class maintains an arbitrary length list of integers. * * In this version:...
/** * This class maintains an arbitrary length list of integers. * * In this version: * 1. The size of the list is *VARIABLE* after the object is created. * 2. The code assumes there is at least one element in the list. * * This class introduces the use of structural recursion. * * @author Raymond Lister * @version May 2016 * */ public class ListOfNVersion03PartB {    private int thisNumber; // the number stored in this node...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT