-2

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?

Josephus
  • 1
  • 2
  • 1
    Welcome to Stack Overflow. Please take the time to read [The Tour](http://stackoverflow.com/tour) and refer to the material from the [Help Center](http://stackoverflow.com/help/asking) what and how you can ask here. – πάντα ῥεῖ Dec 23 '16 at 05:28
  • `reserve()` doesn't change the size of the vector. The vector is still empty. An attempt to access any element, at any index, therefore exhibits undefined behavior. – Igor Tandetnik Dec 23 '16 at 05:28
  • Use `resize()` instead of `reserve()` – πάντα ῥεῖ Dec 23 '16 at 05:28

2 Answers2

0

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.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
0

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).

Community
  • 1
  • 1
M Kumar
  • 1
  • 1