Accessing a {member of vector} of a {vector of a friendly class}

82 Views Asked by At

I wanted to create a class (Army) that consists of a vector of another class (Human). When trying to access a member of Human through Army I ran into a Segmentation fault.

The following code is reduced to the necessary:

#include <iostream>
#include <vector>

using namespace std;

class Human {
    private:
         vector <int> hair;
    public:
        //The size of the reserved entries is arbitrary.
        Human () {hair.reserve(12);}
        friend class Army;
        int get_hair(int a) {return hair[a];}

};
class Army {
    private:
        vector <Human> armyVec;
    public:
        //The size of the reserved entries is arbitrary.
        Army () {armyVec.reserve(12);}
        Human get_Human(int a) {return armyVec[a];}
};

int main()
{
    Human Viktor;
    Army Sparta;
    cout << Viktor.get_hair(1) << endl; //OK
    Viktor = Sparta.get_Human(2);
    cout << Viktor.get_hair(1) << endl; //OK
    //Now I want to access it directly:
  cout << Sparta.get_Human(2).get_hair(1) << endl;    //Segfault !!!
    cout << "Done" << endl;
    return 0;
}

The output is

0
0
Segmentation fault

It works when "hair" isn't a vector but for example an integer (with changes accordingly). How can one solve this?

2

There are 2 best solutions below

0
On BEST ANSWER

reserve only reserves capacity (aka memory) to hold a number of elements. No elements is added to the vector. You can use resize to add elements.

This little program shows the difference between reserve, capacity, resize and size.

#include <iostream>
#include <vector>

int main() {
    std::vector<int> a;
    a.reserve(10);
    std::cout << "Vector capacity after reserve: " << a.capacity() << std::endl;
    std::cout << "Vector size after reserve: " << a.size() << std::endl;
    a.resize(5);
    std::cout << "Vector capacity after resize: " << a.capacity() << std::endl;
    std::cout << "Vector size after resize: " << a.size() << std::endl;
    return 0;
}

Output:

Vector capacity after reserve: 10
Vector size after reserve: 0
Vector capacity after resize: 10
Vector size after resize: 5

You use reserve when you know that the vector over time will grow to a certain size and you want to avoid multiple memory allocations/copies as it grows. In other words - reserving capacity up front, may improve performance.

0
On

It works when "hair" isn't a vector but for example an integer (with changes accordingly). How can one solve this?

It works when we use the "int hair" instead of Vector only when we use "static int hair". Even though the Human object is not initialised in Army, the "static int" value will always be available over the class(strictly typed here).