0

I'm fairly new to C++ and wrote a polynomial class using std::vector. Everything works fine, until I try to invoke the function getCoeff(int index) which should return the coefficient at a specific index. In my case getCoeff(0) should return the 0th coefficient which is '1'.

Instead I receive this error when compiling with g++:

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

Polynomial.h:

#include<iostream>
#include<vector>

using namespace std;

class Polynomial
{
    public:
    Polynomial(int deg, std::vector<int> coeff);
    Polynomial(const Polynomial & p);
    ~Polynomial();
    const int getCoeff(int index);

    private:
    int degree;
    std::vector<int> coefficient;

};

Polynomial::Polynomial(int deg, std::vector<int> coeff)
{
    degree = deg;
    std::vector<int> coefficient(deg);
    for( int i = degree; i >= 0; i--) 
        coefficient[i] = coeff[i];
}

Polynomial::Polynomial(const Polynomial & p)
{
    degree=p.degree;
    std::vector<int> coefficient(p.degree);
    for ( int i=p.degree; i>= 0; i-- )
        coefficient[i] = p.coefficient[i];
}

const int Polynomial::getCoeff(int index)
{
    return coefficient[index];
}

Polynomial::~Polynomial()
{
    //delete[] & coefficient;
    coefficient.clear();
}

And the main file, in which I created a test Polynomial test1 which has a degree of 3 and the coefficients 1,9,3,4 (Note: the std::vector coeff1 is constructed out of the array ko1[ ]):

int main ()
{
    int ko1[] = {1,9,3,4};
    int degree1 = sizeof(ko1)/sizeof(*ko1)-1;

    std::vector<int> coeff1;
    for (int i=0; i<= degree1; i++)
        coeff1.push_back(ko1[i]);

    Polynomial test1(degree1, coeff1);

    cout << "Coefficients: " << endl;
    for (int j=0; j<=degree1; j++)
    cout << coeff1[j] << endl;


    cout << test1.getCoeff(0); //this is where the error occurs

    return 0;

}

I suspect there is an error in my constructor, or the elements obtained from the array are not accepted in the new std::vector Thank you for your help.

Retze
  • 27
  • 2
  • 5
  • 1
    Unrelated, but you know `std::vector` has copy constructors and assignment operators, right? You don't need to copy the elements one by one. – StoryTeller - Unslander Monica Feb 13 '18 at 13:07
  • 1
    Related: https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems – UKMonkey Feb 13 '18 at 13:08
  • 1
    @StoryTeller OP would have to use reverse iterators though and not a straight copy construct. Furthermore the `.clear()` in the dtor is unnecessary. – Borgleader Feb 13 '18 at 13:08
  • @Borgleader - Fair enough. But even then, `std::vector`'s iterator accepting c'tor, as well as the `assign` member should do it. And it would look cleaner, IMO. – StoryTeller - Unslander Monica Feb 13 '18 at 13:09
  • @Borgleader - Actually, each element of the source vector is copied to the corresponding position in the target vector. Why won't simple assignment or copy do? – StoryTeller - Unslander Monica Feb 13 '18 at 13:10
  • @StoryTeller Oh nevermind that part then, I saw a reverse iteration (size - 1 -> 0) and thought they were being reversed. Copy construction should do. – Borgleader Feb 13 '18 at 13:11
  • @StoryTeller You are right, now I removed them and it works fine. The copy constructor was still included from a previous project using arrays instead of vectors. – Retze Feb 13 '18 at 13:40

1 Answers1

4

One recurring error in you code is that it assumes that a vector has elements with indices [0, size], whereas it is a half-open range [0, size). E.g. those loops in constructors should really be for(int i = degree; i-- > 0;) or for(int i = 0; i < degree; ++i) to avoid accessing a non-existent element at index degree .

Another is that constructor Polynomial(int deg, std::vector<int> coeff) fails to initialize coefficient member variable, it initializes a local variable instead. Fix:

Polynomial::Polynomial(int deg, std::vector<int> const& coeff)
    : degree(deg)
    , coefficient(coeff)
{}

Because degree is the number of coefficients, you can remove member degree and use coefficient.size() instead of it.

The code does not need a custom copy constructor or destructor, you can safely remove them or, if necessary, declare them as = default.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • I'm not so sure about that first part. OP push_backs elements using the same condition as they do for iteration. – Borgleader Feb 13 '18 at 13:13
  • @Borgleader See loops in constructors. – Maxim Egorushkin Feb 13 '18 at 13:14
  • @MaximEgorushkin that's also half true. see the call of the ctor `Polynomial test1(degree1, coeff1);` while degree1 is `int degree1 = sizeof(ko1)/sizeof(*ko1)-1;` However, you are right it is missleading using `[0, size]` inside the class... – user1810087 Feb 13 '18 at 13:17
  • @MaximEgorushkin Thanks a lot, it works now as it should. However, I do not understand exactly why, meaning I don't know what the part ": degree(deg) , coefficient(coeff)" means. – Retze Feb 13 '18 at 13:45
  • @Retze That is initializer list syntax, see http://en.cppreference.com/w/cpp/language/initializer_list. – Maxim Egorushkin Feb 13 '18 at 13:50