0

I've been trying to figure out how to deal with pointers & structs. I wrote the following code.

#include <iostream>

using namespace std;

struct Person
{
    char name[20]; //Question 2
    int id;
};

const int max_num_of_childs=10;

struct Family
{
    Person dad;
    Person mom;
    int num_of_childs;
    Person* child[max_num_of_childs];
};

void add_child (Family& f)
{
    char answer;
    do
    {
        if (f.num_of_childs==max_num_of_childs)
        {
            cout << "no more children" <<endl;
            return;
        }

        cout << "more child? Y/N" <<endl;
        cin >> answer;
        if (answer == 'Y')
        {
            f.child[f.num_of_childs] = new Person;
            cout << "enter name and id" << endl;
            cin >> f.child[f.num_of_childs]->name;
            cin >> f.child[f.num_of_childs]->id;
            f.num_of_childs++;
        }
    }
    while (answer=='Y');

    return;
}

void add (Family& f)
{
    cout << "insert dad name & id" << endl;
    cin >> f.dad.name >> f.dad.id;

    cout << "\ninsert mom name & id" << endl;
    cin >> f.mom.name >> f.mom.id;

    add_child (f);
}

void print_child (const Family f) //Question 1
{
    for (int i=0; i<f.num_of_childs; i++)
        cout << "#" << i+1 << "child name: " << f.child[f.num_of_childs]->name << "child id: " << f.child[f.num_of_childs]->id << endl;
}

void print (const Family f)
{
    cout << "dad name: " << f.dad.name << "\tdad id: " << f.dad.id << endl;
    cout << "mom name: " << f.mom.name << "\tmom id: " << f.mom.id << endl;
    print_child (f);
}

int main()
{
    Family f;
    f.num_of_childs=0;
    add(f);
    print(f);

    return 0;
}

Why is the output of print_child() gibberish?

dad name: AAAA  dad id: 11
mom name: BBBB  mom id: 22
1child name: ï Uï∞ u u u h░├evhchild id: 6846053
2child name: ï Uï∞ u u u h░├evhchild id: 6846053

How can I define an array of chars with unlimited length? (using string also requires a defined length).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
shir k
  • 107
  • 6
  • Why aren't you using `std::string`? – Barmar Mar 30 '18 at 09:02
  • And why not use `std::vector` for `child` instead of a fixed-size array? – Barmar Mar 30 '18 at 09:03
  • 2
    Please extract a [mcve]. In particular, eliminate the input from the example code, because it's neither convenient nor safe to always type the input. – Ulrich Eckhardt Mar 30 '18 at 09:03
  • 4
    Why does every family have exactly and always one `mum` and one `dad`, BTW? – Ulrich Eckhardt Mar 30 '18 at 09:05
  • 6
    @UlrichEckhardt We're judging toy exercises on political correctness? – Barmar Mar 30 '18 at 09:06
  • 2
    In `print_child` you need to use `f.child[i]`, not `f.child[f_num_of_childs]` – Barmar Mar 30 '18 at 09:12
  • The code doesn't scale beyond a certain number of children, as others mentioned. It doesn't scale to other, even more conceivable use cases, like grandparents, grandchildren, more than two parents etc. This has nothing to do with political correctness yet, though I'd be guilty if charged of not preventing that misunderstanding. ;) – Ulrich Eckhardt Mar 30 '18 at 09:13
  • Barmar, thanks a lot! :) Ulrich Eckhardt, now that my issue has been solved, I can try working on a realistic family tree :) – shir k Mar 30 '18 at 09:17
  • 3
    Realistic trees can be *hard*, see [Cycles in family tree software](https://stackoverflow.com/questions/6163683/cycles-in-family-tree-software) :-) – Bo Persson Mar 30 '18 at 09:29
  • `print_child()` and `print()` should be taking their inputs by const reference: `void print_child (const Family &f)` and `void print (const Family &f)` – Remy Lebeau Mar 30 '18 at 20:51
  • It looks like gibberish because it IS gibberish. You never allocate the array of pointers "Family.child" Avoid arrays. Use std::vector and std::string. Your assertion that std::string has a fixed size is false. Also, don't say "unlimited length", say arbitrary length. You are always limited by system memory. :) – Kenny Ostrom Mar 30 '18 at 22:15

1 Answers1

1

Why is the output of print_child() gibberish?

In the print_child() method, code is reaching out of initialized range of f.child array. There is:

void print_child (const Family f) //Question 1
{
    for (int i=0; i<f.num_of_childs; i++)
        cout << "#" << i+1 << "child name: " << f.child[f.num_of_childs]->name << "child id: " << f.child[f.num_of_childs]->id << endl;
}

I believe there should be:

void print_child (const Family f) //Question 1
{
    for (int i=0; i<f.num_of_childs; i++)
        cout << "#" << i+1 << "child name: " << f.child[i]->name << "child id: " << f.child[i]->id << endl;
}

i is always smaller then f.num_of_childs, so code will not reach uninitialized memory.

Apart of this there is one more small thing.

Usually integer class members get initialized to 0, but this is not guarantied. I would recommend initialization, to ensure that initial value of num_of_childs is 0 when object of Family class is created:

struct Family
{
    Person dad;
    Person mom;
    int num_of_childs = 0;
    Person* child[max_num_of_childs];
};
atrelinski
  • 432
  • 2
  • 9