Question

[Solved] terminate called after throwing an instance of ‘std::out_of_range’

I’m a absolute beginner for programming. I got this error while building up the following code.

error: terminate called after throwing an instance of 'std::out_of_range' what(): vector::_M_range_check: __n (which is 8) >= this->size() (which is 8) Aborted (core dumped)

#include<iostream>
#include<vector>
#include<string>
#include<iomanip>
using namespace std;
int main()
{
    cout<<"n Welcome to space travel calculation program";

    string cPlanet, name;
    double weight, speed, tTime, nWeight;
    int num;
    vector<string> planet;
    vector<int> distance;
    vector<double> sGravity;

    planet.push_back("Mercury");
    distance.push_back(36);
    sGravity.push_back(0.27);

    planet.push_back("Venus");
    distance.push_back(67);
    sGravity.push_back(0.86);

    planet.push_back("Earth");
    distance.push_back(93);
    sGravity.push_back(1.00);

    planet.push_back("Mars");
    distance.push_back(141);
    sGravity.push_back(0.37);

    planet.push_back("Jupiter");
    distance.push_back(483);
    sGravity.push_back(2.64);

    planet.push_back("Saturn");
    distance.push_back(886);
    sGravity.push_back(1.17);

    planet.push_back("Uranus");
    distance.push_back(1782);
    sGravity.push_back(0.92);

    planet.push_back("Neptune");
    distance.push_back(2793);
    sGravity.push_back(1.44);
    num=planet.size();

    cout<<"n Please tell me your name: ";
    getline(cin,name);


    cout<<"n Please choose which planet you want to travel to from the following list:"
        <<"n 1.Mercury"
        <<"n 2.Venus"
        <<"n 3.Earth"
        <<"n 4.Mars"
        <<"n 5.Jupiter"
        <<"n 6.Saturn"
        <<"n 7.Uranus"
        <<"n 8.Neptune       :";
    getline(cin,cPlanet);

    cout<<"n What is your weight on Earth?";
    cin>>weight;

    cout<<"n At what speed do you wish to travel? :";
    cin>>speed;

    if(cPlanet==planet.at(num))
    {
        tTime=(distance.at(num))/speed;
        nWeight=weight*sGravity.at(num);

        cout<<"n Your Name: "<<name
            <<"n Weight On Earth: "<<weight
            <<"n Planet you wish to visit: "<<cPlanet
            <<"n The speed you will be travelling at: "<<speed
            <<"n Total time it will take to reach "<<planet.at(num)<<": "<<tTime
            <<"n Your weight on "<<planet.at(num)<<": "<<nWeight;
    }

    return 0;
}
Enquirer: santosh

||

Solution #1:

Array and vector indices in C++ run from 0 to size – 1. Thus when you say

num=planet.size();

and later

if(cPlanet==planet.at(num))

you are trying to access one past the end of the vector planet. The at member function then throws an exception of type std::out_of_range that is never caught, and your program terminates because of that.

It looks as though you wanted to find the vector index corresponding to a planet name; you could do that with std::find and std::distance as follows:

num = std::distance(planet.begin(), std::find(planet.begin(), planet.end(), cPlanet));

this will return planet.size() if cPlanet is not found. However, it would probably be nicer to implement the whole thing with a std::map.

Respondent: Wintermute

Solution #2:

Here’s a simpler program to reproduce the behaviour:

#include <vector>

int main()
{
    std::vector<int> v;
    v.push_back(123); // v has 1 element  [0 to 0]
    v.push_back(456); // v has 2 elements [0 to 1]
    v.push_back(789); // v has 3 elements [0 to 2]
    int x1 = v.at(0); // 123
    int x2 = v.at(1); // 456
    int x3 = v.at(2); // 789
    int x4 = v.at(3); // exception
}

The at member function throws an exception if you try to access a non-existing element.

While that principally sounds like a good thing, it turns out to be pretty useless in practice. Using an illegal vector index is almost surely a programming error, and exceptions should not be thrown for programming errors.

You could catch the std::out_of_range exception to “recover” from the error or “handle” it, but seriously, what could you possibly do at such a low level of program logic?

For std::vector, prefer the [] operator. In your case:

tTime = distance[num] / speed;

[] is like at, but takes an entirely different stance on programming errors; at is like “if you should ever call me with an illegal index, I’ll throw an exception so that we can somehow carry on, shall we?”, whereas with the [] operator the behaviour is undefined for illegal vector indices. This means a C++ implementation is allowed to just terminate the program without any chance of accidentally catching an exception and “continuing somehow”. It depends on how you invoke the compiler and generally requires you to examine your compiler’s configuration options (for example those for VC++ or those for GCC).

Terminating as quickly as possible is the right thing to do when you find out that your own code is wrong. Do not get used to at‘s behaviour.

Respondent: Christian Hackl

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Most Popular

To Top
India and Pakistan’s steroid-soaked rhetoric over Kashmir will come back to haunt them both clenbuterol australia bossier man pleads guilty for leadership role in anabolic steriod distribution conspiracy